Skip to content

Commit

Permalink
Polling only happens when app is in foreground
Browse files Browse the repository at this point in the history
  • Loading branch information
LilianaFaustinoDev committed Sep 29, 2022
1 parent 0ce7b0b commit 93d0403
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 12 deletions.
5 changes: 5 additions & 0 deletions app/src/main/java/tech/relaycorp/courier/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tech.relaycorp.courier
import android.app.Application
import android.os.Build
import android.os.StrictMode
import tech.relaycorp.courier.background.ForegroundAppMonitor
import tech.relaycorp.courier.background.WifiHotspotStateWatcher
import tech.relaycorp.courier.common.Logging
import tech.relaycorp.courier.common.di.AppComponent
Expand All @@ -16,6 +17,9 @@ open class App : Application() {
@Inject
lateinit var wifiHotspotStateWatcher: WifiHotspotStateWatcher

@Inject
lateinit var foregroundAppMonitor: ForegroundAppMonitor

open val component: AppComponent by lazy {
DaggerAppComponent.builder()
.appModule(AppModule(this))
Expand All @@ -36,6 +40,7 @@ open class App : Application() {
component.inject(this)
setupLogger()
setupStrictMode()
registerActivityLifecycleCallbacks(foregroundAppMonitor)
wifiHotspotStateWatcher.start()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package tech.relaycorp.courier.background

import android.app.Activity
import android.app.Application
import android.os.Bundle
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ForegroundAppMonitor
@Inject constructor() : Application.ActivityLifecycleCallbacks {
private val activityCountFlow = MutableStateFlow(0)

fun observe() = activityCountFlow.map { if (it == 0) State.Background else State.Foreground }

override fun onActivityStarted(activity: Activity) {
activityCountFlow.value++
}

override fun onActivityStopped(activity: Activity) {
activityCountFlow.value--
}

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) = Unit
override fun onActivityResumed(activity: Activity) = Unit
override fun onActivityPaused(activity: Activity) = Unit
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit
override fun onActivityDestroyed(activity: Activity) = Unit

enum class State {
Foreground, Background
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ import android.net.wifi.WifiManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import tech.relaycorp.cogrpc.server.GatewayIPAddressException
import tech.relaycorp.cogrpc.server.Networking
import tech.relaycorp.courier.common.BehaviorChannel
import tech.relaycorp.courier.common.Logging.logger
import tech.relaycorp.courier.common.tickerFlow
import javax.inject.Inject
Expand All @@ -26,11 +27,12 @@ import kotlin.time.Duration.Companion.seconds
@Singleton
class WifiHotspotStateWatcher
@Inject constructor(
private val context: Context
private val context: Context,
private val foregroundAppMonitor: ForegroundAppMonitor
) {

private val state = BehaviorChannel(WifiHotspotState.Disabled)
fun state() = state.asFlow().distinctUntilChanged()
private val state = MutableStateFlow(WifiHotspotState.Disabled)
fun state() = state.asStateFlow()

private var pollingGatewayAddressesJob: Job? = null

Expand All @@ -54,8 +56,14 @@ class WifiHotspotStateWatcher
}

private fun startPollingGatewayAddresses() {
pollingGatewayAddressesJob = tickerFlow(POLLING_GATEWAY_ADDRESS_INTERVAL)
.map {
pollingGatewayAddressesJob = foregroundAppMonitor.observe()
.flatMapLatest {
if (it == ForegroundAppMonitor.State.Foreground) {
tickerFlow(POLLING_GATEWAY_ADDRESS_INTERVAL)
} else {
emptyFlow()
}
}.map {
try {
Networking.getGatewayIpAddress()
WifiHotspotState.Enabled
Expand All @@ -66,13 +74,14 @@ class WifiHotspotStateWatcher
.distinctUntilChanged()
.onEach {
logger.info("Hotspot State $it")
state.send(it)
state.value = it
}
.launchIn(CoroutineScope(Dispatchers.IO))
}

private fun stopPollingGatewayAddresses() {
pollingGatewayAddressesJob?.cancel()
pollingGatewayAddressesJob = null
}

private val wifiApStateChangeReceiver by lazy {
Expand All @@ -81,14 +90,13 @@ class WifiHotspotStateWatcher
if (intent.action != WIFI_AP_STATE_CHANGED_ACTION) return

val stateFlag = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0)
logger.info("Wifi State $stateFlag")
state.trySendBlocking(
logger.info("Hotspot State $stateFlag")
state.value =
if (stateFlag == WIFI_AP_STATE_ENABLED) {
WifiHotspotState.Enabled
} else {
WifiHotspotState.Disabled
}
)
}
}
}
Expand Down

0 comments on commit 93d0403

Please sign in to comment.