ezralazuardy/orb

View on GitHub
orb/src/main/java/com/ezralazuardy/orb/Orb.kt

Summary

Maintainability
A
0 mins
Test Coverage
/*
 * Created by Ezra Lazuardy on 5/6/20 8:23 AM
 * Copyright (c) 2020. All rights reserved.
 * Last modified 5/6/20 7:55 AM
 */

package com.ezralazuardy.orb

import android.annotation.TargetApi
import android.content.Context
import android.os.Build
import androidx.annotation.MainThread
import androidx.lifecycle.Observer
import com.ezralazuardy.orb.OrbHelper.lifecycleOwner
import com.ezralazuardy.orb.OrbHelper.orbOptions

/**
 * Orb is a class that provide functionality to observe network events.
 * Make sure to call Orb.with() at least once in current context (view) before calling other
 * function to initialize the current context and lifecycle observer that will used in OrbEngine.
 * If don't, Orb will @throws an OrbError.
 *
 * Orb is not allowing constructor invocation. This means that client code must use .with() to
 * create a new instance of Orb.
 */
class Orb private constructor() {

    private lateinit var context: Context
    private lateinit var orbEngine: OrbEngine
    private lateinit var observer: Observer<OrbResponse>
    private var orbListener: OrbListener? = null
        set(value) {
            if (this::orbEngine.isInitialized) this.orbEngine.orbListener = value
            field = value
        }

    companion object {
        /**
         * Orb.with() used to initialize Orb functionality by instantiating an OrbEngine.
         * This method will construct the parameter that used in OrbEngine. Make sure to call
         * this method first before calling the other method as it is used to initializing the Orb.
         *
         * @param context
         * @param orbOptions
         */
        @MainThread
        fun with(context: Context, options: OrbOptions = OrbOptions()): Orb = Orb().apply {
            if (!this::context.isInitialized) {
                this.context = context
                this.orbEngine = OrbEngine(this.context, options)
            }
        }
    }

    /**
     * Orb.setListener() used to install an OrbListener to current Orb instance. This means that
     * now Orb can notify via interface listener to the client code.
     *
     * @param orbListener
     */
    @MainThread
    fun setListener(orbListener: OrbListener): Orb = this.apply {
        this.orbListener = orbListener
    }

    /**
     * Orb.observe() used to instruct Orb to start observing the OrbEngine.
     * This means that client code is now can start observing the network events by using OrbEngine
     * Live Data. The OrbEngine will notify by using an object OrbResponse that contain current
     * network state information. This method require lambda parameter to be invoked when network
     * event changes.
     *
     * Calling this method before {@link Orb#with()} will @throws an OrbError.
     *
     * OrbListener.onOrbObserve() will be called in this method.
     *
     * @param lambda
     */
    @MainThread
    fun observe(observer: (OrbResponse) -> Unit): Orb {
        this.orbListener?.onOrbObserve()
        try {
            if (context.lifecycleOwner() != null) {
                if (this::context.isInitialized) {
                    if (this::observer.isInitialized) orbEngine.removeObserver(this.observer)
                    this.observer = Observer(observer)
                    orbEngine.observe(context.lifecycleOwner()!!, this.observer)
                } else throw OrbError(OrbError.ORB_NOT_INITIALIZED)
            } else throw OrbError(OrbError.LIFECYCLE_OWNER_NOT_FOUND)
        } catch (e: OrbError) {
            e.printStackTrace()
        }
        return this
    }

    /**
     * Orb.stop() used to instruct Orb to stop observing the current OrbEngine.
     * This means that current context will get OrbResponse no more. You need to call
     * Orb.observe() in order to start observing the network events again.
     *
     * Calling this method before {@link Orb#with()} will @throws an OrbError.
     *
     * This method return boolean true if action succeed and false if don't.
     *
     * OrbListener.onOrbStop() will be called in this method.
     */
    @MainThread
    fun stop(): Boolean {
        this.orbListener?.onOrbStop()
        try {
            if (this::orbEngine.isInitialized) {
                if (this::observer.isInitialized) {
                    orbEngine.removeObserver(this.observer)
                    return true
                } else throw OrbError(OrbError.ORB_NOT_INITIALIZED)
            } else throw OrbError(OrbError.ORB_NOT_INITIALIZED)
        } catch (e: OrbError) {
            e.printStackTrace()
        }
        return false
    }

    /**
     * allowBluetooth() is a helper function to toggle the bluetooth network type filtering in Orb.
     * Disallowing bluetooth will make Orb to not detecting bluetooth network type.
     *
     * Default parameter is boolean true.
     *
     * @param boolean
     */
    fun allowBluetooth(state: Boolean = true): Orb {
        this.orbEngine.setOption(OrbType.BLUETOOTH, state)
        return this
    }

    /**
     * allowCellular() is a helper function to toggle the cellular network type filtering in Orb.
     * Disallowing cellular will make Orb to not detecting cellular network type.
     *
     * Default parameter is boolean true.
     *
     * @param boolean
     */
    fun allowCellular(state: Boolean = true): Orb {
        this.orbEngine.setOption(OrbType.CELLULAR, state)
        return this
    }

    /**
     * allowEthernet() is a helper function to toggle the ethernet network type filtering in Orb.
     * Disallowing ethernet will make Orb to not detecting ethernet network type.
     *
     * Default parameter is boolean true.
     *
     * @param boolean
     */
    fun allowEthernet(state: Boolean = true): Orb {
        this.orbEngine.setOption(OrbType.ETHERNET, state)
        return this
    }

    /**
     * allowLowPan() is a helper function to toggle the low pan network type filtering in Orb.
     * Disallowing low pan will make Orb to not detecting low pan network type.
     *
     * This function will only work on API Level 23+ (Marshmallow), otherwise Orb will not detecting
     * low pan network type at all.
     *
     * Default parameter is boolean true.
     *
     * @param boolean
     */
    @TargetApi(Build.VERSION_CODES.M)
    fun allowLowPan(state: Boolean = true): Orb {
        this.orbEngine.setOption(OrbType.LOWPAN, state)
        return this
    }

    /**
     * allowVPN() is a helper function to toggle the VPN network type filtering in Orb.
     * Disallowing VPN will make Orb to not detecting VPN network type.
     *
     * Default parameter is boolean true.
     *
     * @param boolean
     */
    fun allowVPN(state: Boolean = true): Orb {
        this.orbEngine.setOption(OrbType.VPN, state)
        return this
    }

    /**
     * allowWifi() is a helper function to toggle the wifi network type filtering in Orb.
     * Disallowing wifi will make Orb to not detecting wifi network type.
     *
     * Default parameter is boolean true.
     *
     * @param boolean
     */
    fun allowWifi(state: Boolean = true): Orb {
        this.orbEngine.setOption(OrbType.WIFI, state)
        return this
    }

    /**
     * allowWifiAware() is a helper function to toggle the wifi aware network type filtering in Orb.
     * Disallowing wifi aware will make Orb to not detecting wifi aware network type.
     *
     * This function will only work on API Level 23+ (Marshmallow), otherwise Orb will not detecting
     * wifi aware network type at all.
     *
     * Default parameter is boolean true.
     *
     * @param boolean
     */
    @TargetApi(Build.VERSION_CODES.M)
    fun allowWifiAware(state: Boolean = true): Orb {
        this.orbEngine.setOption(OrbType.WIFI_AWARE, state)
        return this
    }

    /**
     * allowBluetoothOnly() is a helper function to enable the bluetooth only network type filtering in Orb.
     * Calling this function will make Orb to detect bluetooth network type only.
     */
    fun allowBluetoothOnly(): Orb {
        this.orbEngine.orbOptions = orbOptions {
            mapOf(
                OrbType.CELLULAR to false,
                OrbType.ETHERNET to false,
                OrbType.LOWPAN to false,
                OrbType.VPN to false,
                OrbType.WIFI to false,
                OrbType.WIFI_AWARE to false
            )
        }
        return this
    }

    /**
     * allowCelullarOnly() is a helper function to enable the cellular only network type filtering in Orb.
     * Calling this function will make Orb to detect cellular network type only.
     */
    fun allowCelullarOnly(): Orb {
        this.orbEngine.orbOptions = orbOptions {
            mapOf(
                OrbType.BLUETOOTH to false,
                OrbType.ETHERNET to false,
                OrbType.LOWPAN to false,
                OrbType.VPN to false,
                OrbType.WIFI to false,
                OrbType.WIFI_AWARE to false
            )
        }
        return this
    }

    /**
     * allowEthernetOnly() is a helper function to enable the ethernet only network type filtering in Orb.
     * Calling this function will make Orb to detect ethernet network type only.
     */
    fun allowEthernetOnly(): Orb {
        this.orbEngine.orbOptions = orbOptions {
            mapOf(
                OrbType.BLUETOOTH to false,
                OrbType.CELLULAR to false,
                OrbType.LOWPAN to false,
                OrbType.VPN to false,
                OrbType.WIFI to false,
                OrbType.WIFI_AWARE to false
            )
        }
        return this
    }

    /**
     * allowLowPanOnly() is a helper function to enable the low pan only network type filtering in Orb.
     * Calling this function will make Orb to detect low pan network type only.
     *
     * This function will only work on API Level 23+ (Marshmallow), otherwise Orb will not detecting
     * low pan network type at all.
     */
    @TargetApi(Build.VERSION_CODES.M)
    fun allowLowPanOnly(): Orb {
        this.orbEngine.orbOptions = orbOptions {
            mapOf(
                OrbType.BLUETOOTH to false,
                OrbType.CELLULAR to false,
                OrbType.ETHERNET to false,
                OrbType.VPN to false,
                OrbType.WIFI to false,
                OrbType.WIFI_AWARE to false
            )
        }
        return this
    }

    /**
     * allowWifiOnly() is a helper function to enable the wifi only network type filtering in Orb.
     * Calling this function will make Orb to detect wifi network type only.
     */
    fun allowWifiOnly(): Orb {
        this.orbEngine.orbOptions = orbOptions {
            mapOf(
                OrbType.BLUETOOTH to false,
                OrbType.CELLULAR to false,
                OrbType.ETHERNET to false,
                OrbType.VPN to false,
                OrbType.LOWPAN to false,
                OrbType.WIFI_AWARE to false
            )
        }
        return this
    }

    /**
     * allowWifiAwareOnly() is a helper function to enable the wifi aware only network type filtering in Orb.
     * Calling this function will make Orb to detect wifi aware network type only.
     *
     * This function will only work on API Level 23+ (Marshmallow), otherwise Orb will not detecting
     * wifi aware network type at all.
     */
    @TargetApi(Build.VERSION_CODES.M)
    fun allowWifiAwareOnly(): Orb {
        this.orbEngine.orbOptions = orbOptions {
            mapOf(
                OrbType.BLUETOOTH to false,
                OrbType.CELLULAR to false,
                OrbType.ETHERNET to false,
                OrbType.VPN to false,
                OrbType.LOWPAN to false,
                OrbType.WIFI to false
            )
        }
        return this
    }
}