[Status Bar] Fetch WifiManager.isWifiEnabled in the background.

Note: The `initialValue =` in #logDiffsForTable and #stateIn can't call
suspending functions, so they're updated to just be `false`. To make up
for that, an #onStart is added that will fetch the value and the flow is
updated to SharingStarted.Eagerly so that the value is immediately
fetched. This ensures that
WifiRepositoryImplTest#isWifiEnabled_initiallyGetsWifiManagerValue still
passes.

Fixes: 270039915
Test: toggle wifi on/off > verify wifi icon responds appropriately
Test: turn wifi on > restart device > verify isWifiEnabled is true on
start (verified via logging)
Test: turn wifi off > restart device > verify isWifiEnabled is false on
start (verified via logging)
Test: atest WifiRepositoryImplTest

Change-Id: Ifd577a0ae2c495a9d96619851021a37c4bff3cd7
This commit is contained in:
Caitlin Shkuratov
2023-07-10 21:07:39 +00:00
parent e6ac183848
commit c53c72ee19
4 changed files with 22 additions and 6 deletions

View File

@@ -34,6 +34,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.logDiffsForTable
@@ -48,6 +49,7 @@ import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
@@ -60,7 +62,9 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
/** Real implementation of [WifiRepository]. */
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@@ -76,8 +80,9 @@ constructor(
logger: WifiInputLogger,
@WifiTableLog wifiTableLogBuffer: TableLogBuffer,
@Main mainExecutor: Executor,
@Background private val bgDispatcher: CoroutineDispatcher,
@Application scope: CoroutineScope,
wifiManager: WifiManager,
private val wifiManager: WifiManager,
) : RealWifiRepository {
private val wifiStateChangeEvents: Flow<Unit> =
@@ -93,20 +98,25 @@ constructor(
// have changed.
override val isWifiEnabled: StateFlow<Boolean> =
merge(wifiNetworkChangeEvents, wifiStateChangeEvents)
.mapLatest { wifiManager.isWifiEnabled }
.onStart { emit(Unit) }
.mapLatest { isWifiEnabled() }
.distinctUntilChanged()
.logDiffsForTable(
wifiTableLogBuffer,
columnPrefix = "",
columnName = "isEnabled",
initialValue = wifiManager.isWifiEnabled,
initialValue = false,
)
.stateIn(
scope = scope,
started = SharingStarted.WhileSubscribed(),
initialValue = wifiManager.isWifiEnabled,
started = SharingStarted.Eagerly,
initialValue = false,
)
// [WifiManager.isWifiEnabled] is a blocking IPC call, so fetch it in the background.
private suspend fun isWifiEnabled(): Boolean =
withContext(bgDispatcher) { wifiManager.isWifiEnabled }
override val isWifiDefault: StateFlow<Boolean> =
connectivityRepository.defaultConnections
// TODO(b/274493701): Should wifi be considered default if it's carrier merged?
@@ -289,6 +299,7 @@ constructor(
private val logger: WifiInputLogger,
@WifiTableLog private val wifiTableLogBuffer: TableLogBuffer,
@Main private val mainExecutor: Executor,
@Background private val bgDispatcher: CoroutineDispatcher,
@Application private val scope: CoroutineScope,
) {
fun create(wifiManager: WifiManager): WifiRepositoryImpl {
@@ -299,6 +310,7 @@ constructor(
logger,
wifiTableLogBuffer,
mainExecutor,
bgDispatcher,
scope,
wifiManager,
)

View File

@@ -159,6 +159,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
mock(),
mock(),
FakeExecutor(FakeSystemClock()),
dispatcher,
testScope.backgroundScope,
mock(),
)

View File

@@ -83,6 +83,7 @@ class WifiRepositorySwitcherTest : SysuiTestCase() {
logger,
tableLogger,
mainExecutor,
testDispatcher,
testScope.backgroundScope,
wifiManager,
)

View File

@@ -76,7 +76,8 @@ class WifiRepositoryImplTest : SysuiTestCase() {
private lateinit var executor: Executor
private lateinit var connectivityRepository: ConnectivityRepository
private val testScope = TestScope(UnconfinedTestDispatcher())
private val dispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(dispatcher)
@Before
fun setUp() {
@@ -1301,6 +1302,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
logger,
tableLogger,
executor,
dispatcher,
testScope.backgroundScope,
wifiManager,
)