From 4d313e1c166bb06944b86e7567d28ae3c61f79d0 Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Wed, 28 Dec 2022 17:18:26 +0000 Subject: [PATCH 1/5] [SB Refactor] Provide a disabled wifi repo if there's no wifi manager. This allows WifiRepositoryImpl to use a non-null WifiManager, which removes a lot of null checks throughout the pipeline. Bug: 238425913 Test: verify wifi icon still works Test: verify wifi demo mode still works Test: verify that, when WifiManager is null, the wifi icon never shows Test: all tests in statusbar.pipeline.wifi Change-Id: I8de76ad554769e91f1612ddfb3e9fa6dfa9bc6ed --- .../dagger/StatusBarPipelineModule.kt | 23 +++- .../wifi/data/model/WifiNetworkModel.kt | 43 ++++-- .../wifi/data/repository/WifiRepository.kt | 10 ++ .../data/repository/WifiRepositorySwitcher.kt | 2 +- .../repository/demo/DemoWifiRepository.kt | 2 +- .../repository/prod/DisabledWifiRepository.kt | 49 +++++++ .../repository/prod/WifiRepositoryImpl.kt | 125 ++++++++++-------- .../wifi/domain/interactor/WifiInteractor.kt | 1 + .../wifi/ui/viewmodel/WifiViewModel.kt | 37 +++--- .../wifi/data/model/WifiNetworkModelTest.kt | 6 - .../prod/DisabledWifiRepositoryTest.kt | 57 ++++++++ .../repository/prod/WifiRepositoryImplTest.kt | 27 +--- .../interactor/WifiInteractorImplTest.kt | 20 +++ .../WifiViewModelIconParameterizedTest.kt | 12 +- .../wifi/ui/viewmodel/WifiViewModelTest.kt | 5 +- 15 files changed, 286 insertions(+), 133 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt index 0d01715715c07..0993ab3701f62 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.pipeline.dagger +import android.net.wifi.WifiManager import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton import com.android.systemui.log.table.TableLogBuffer @@ -35,8 +36,11 @@ import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxyImpl import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl +import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositorySwitcher +import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.DisabledWifiRepository +import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import dagger.Binds @@ -78,9 +82,23 @@ abstract class StatusBarPipelineModule { @ClassKey(MobileUiAdapter::class) abstract fun bindFeature(impl: MobileUiAdapter): CoreStartable - @Module companion object { - @JvmStatic + @Provides + @SysUISingleton + fun provideRealWifiRepository( + wifiManager: WifiManager?, + disabledWifiRepository: DisabledWifiRepository, + wifiRepositoryImplFactory: WifiRepositoryImpl.Factory, + ): RealWifiRepository { + // If we have a null [WifiManager], then the wifi repository should be permanently + // disabled. + return if (wifiManager == null) { + disabledWifiRepository + } else { + wifiRepositoryImplFactory.create(wifiManager) + } + } + @Provides @SysUISingleton @WifiTableLog @@ -88,7 +106,6 @@ abstract class StatusBarPipelineModule { return factory.create("WifiTableLog", 100) } - @JvmStatic @Provides @SysUISingleton @AirplaneTableLog diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt index a682a5711a6f5..4251d18357f7d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt @@ -23,6 +23,33 @@ import com.android.systemui.log.table.Diffable /** Provides information about the current wifi network. */ sealed class WifiNetworkModel : Diffable { + /** + * A model representing that we couldn't fetch any wifi information. + * + * This is only used with [DisabledWifiRepository], where [WifiManager] is null. + */ + object Unavailable : WifiNetworkModel() { + override fun toString() = "WifiNetwork.Unavailable" + override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) { + if (prevVal is Unavailable) { + return + } + + logFull(row) + } + + override fun logFull(row: TableRowLogger) { + row.logChange(COL_NETWORK_TYPE, TYPE_UNAVAILABLE) + row.logChange(COL_NETWORK_ID, NETWORK_ID_DEFAULT) + row.logChange(COL_VALIDATED, false) + row.logChange(COL_LEVEL, LEVEL_DEFAULT) + row.logChange(COL_SSID, null) + row.logChange(COL_PASSPOINT_ACCESS_POINT, false) + row.logChange(COL_ONLINE_SIGN_UP, false) + row.logChange(COL_PASSPOINT_NAME, null) + } + } + /** A model representing that we have no active wifi network. */ object Inactive : WifiNetworkModel() { override fun toString() = "WifiNetwork.Inactive" @@ -87,13 +114,8 @@ sealed class WifiNetworkModel : Diffable { /** * The wifi signal level, guaranteed to be 0 <= level <= 4. - * - * Null if we couldn't fetch the level for some reason. - * - * TODO(b/238425913): The level will only be null if we have a null WifiManager. Is there a - * way we can guarantee a non-null WifiManager? */ - val level: Int? = null, + val level: Int, /** See [android.net.wifi.WifiInfo.ssid]. */ val ssid: String? = null, @@ -108,7 +130,7 @@ sealed class WifiNetworkModel : Diffable { val passpointProviderFriendlyName: String? = null, ) : WifiNetworkModel() { init { - require(level == null || level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) { + require(level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) { "0 <= wifi level <= 4 required; level was $level" } } @@ -125,11 +147,7 @@ sealed class WifiNetworkModel : Diffable { row.logChange(COL_VALIDATED, isValidated) } if (prevVal !is Active || prevVal.level != level) { - if (level != null) { - row.logChange(COL_LEVEL, level) - } else { - row.logChange(COL_LEVEL, LEVEL_DEFAULT) - } + row.logChange(COL_LEVEL, level) } if (prevVal !is Active || prevVal.ssid != ssid) { row.logChange(COL_SSID, ssid) @@ -190,6 +208,7 @@ sealed class WifiNetworkModel : Diffable { } const val TYPE_CARRIER_MERGED = "CarrierMerged" +const val TYPE_UNAVAILABLE = "Unavailable" const val TYPE_INACTIVE = "Inactive" const val TYPE_ACTIVE = "Active" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt index 53525f254e1d4..ac4d55c3a29cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt @@ -34,3 +34,13 @@ interface WifiRepository { /** Observable for the current wifi network activity. */ val wifiActivity: StateFlow } + +/** + * A no-op interface used for Dagger bindings. + * + * [WifiRepositorySwitcher] needs to inject the "real" wifi repository, which could either be the + * full [WifiRepositoryImpl] or just [DisabledWifiRepository]. Having this interface lets us bind + * [RealWifiRepository], and then [WifiRepositorySwitcher] will automatically get the correct real + * repository. + */ +interface RealWifiRepository : WifiRepository diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt index be86620e01f33..2cb81c8097168 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcher.kt @@ -58,7 +58,7 @@ import kotlinx.coroutines.flow.stateIn class WifiRepositorySwitcher @Inject constructor( - private val realImpl: WifiRepositoryImpl, + private val realImpl: RealWifiRepository, private val demoImpl: DemoWifiRepository, private val demoModeController: DemoModeController, @Application scope: CoroutineScope, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt index 7890074cf8a26..be3d7d4e65c41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt @@ -89,7 +89,7 @@ constructor( WifiNetworkModel.Active( networkId = DEMO_NET_ID, isValidated = validated ?: true, - level = level, + level = level ?: 0, ssid = ssid, // These fields below aren't supported in demo mode, since they aren't needed to satisfy diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt new file mode 100644 index 0000000000000..5d4a6664a19a3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepository.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel +import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel +import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +/** + * Implementation of wifi repository used when wifi is permanently disabled on the device. + * + * This repo should only exist when [WifiManager] is null, which means that we can never fetch any + * wifi information. + */ +@SysUISingleton +class DisabledWifiRepository @Inject constructor() : RealWifiRepository { + override val isWifiEnabled: StateFlow = MutableStateFlow(false).asStateFlow() + + override val isWifiDefault: StateFlow = MutableStateFlow(false).asStateFlow() + + override val wifiNetwork: StateFlow = MutableStateFlow(NETWORK).asStateFlow() + + override val wifiActivity: StateFlow = + MutableStateFlow(ACTIVITY).asStateFlow() + + companion object { + private val NETWORK = WifiNetworkModel.Unavailable + private val ACTIVITY = DataActivityModel(hasActivityIn = false, hasActivityOut = false) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt index c8c94e1029996..219fa839a2abf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt @@ -29,7 +29,6 @@ import android.net.NetworkRequest import android.net.wifi.WifiInfo import android.net.wifi.WifiManager import android.net.wifi.WifiManager.TrafficStateCallback -import android.util.Log import com.android.settingslib.Utils import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow @@ -40,11 +39,11 @@ import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel +import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository import java.util.concurrent.Executor import javax.inject.Inject @@ -53,12 +52,9 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.stateIn @@ -75,8 +71,8 @@ class WifiRepositoryImpl @Inject constructor( @WifiTableLog wifiTableLogBuffer: TableLogBuffer, @Main mainExecutor: Executor, @Application scope: CoroutineScope, - wifiManager: WifiManager?, -) : WifiRepository { + wifiManager: WifiManager, +) : RealWifiRepository { private val wifiStateChangeEvents: Flow = broadcastDispatcher.broadcastFlow( IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION) @@ -86,28 +82,24 @@ class WifiRepositoryImpl @Inject constructor( private val wifiNetworkChangeEvents: MutableSharedFlow = MutableSharedFlow(extraBufferCapacity = 1) + // Because [WifiManager] doesn't expose a wifi enabled change listener, we do it + // internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may + // have changed. override val isWifiEnabled: StateFlow = - if (wifiManager == null) { - MutableStateFlow(false).asStateFlow() - } else { - // Because [WifiManager] doesn't expose a wifi enabled change listener, we do it - // internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may - // have changed. - merge(wifiNetworkChangeEvents, wifiStateChangeEvents) - .mapLatest { wifiManager.isWifiEnabled } - .distinctUntilChanged() - .logDiffsForTable( - wifiTableLogBuffer, - columnPrefix = "", - columnName = "isWifiEnabled", - initialValue = wifiManager.isWifiEnabled, - ) - .stateIn( - scope = scope, - started = SharingStarted.WhileSubscribed(), - initialValue = wifiManager.isWifiEnabled - ) - } + merge(wifiNetworkChangeEvents, wifiStateChangeEvents) + .mapLatest { wifiManager.isWifiEnabled } + .distinctUntilChanged() + .logDiffsForTable( + wifiTableLogBuffer, + columnPrefix = "", + columnName = "isWifiEnabled", + initialValue = wifiManager.isWifiEnabled, + ) + .stateIn( + scope = scope, + started = SharingStarted.WhileSubscribed(), + initialValue = wifiManager.isWifiEnabled, + ) override val isWifiDefault: StateFlow = conflatedCallbackFlow { // Note: This callback doesn't do any logging because we already log every network change @@ -217,29 +209,24 @@ class WifiRepositoryImpl @Inject constructor( ) override val wifiActivity: StateFlow = - if (wifiManager == null) { - Log.w(SB_LOGGING_TAG, "Null WifiManager; skipping activity callback") - flowOf(ACTIVITY_DEFAULT) - } else { - conflatedCallbackFlow { - val callback = TrafficStateCallback { state -> - logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state)) - trySend(state.toWifiDataActivityModel()) - } - wifiManager.registerTrafficStateCallback(mainExecutor, callback) - awaitClose { wifiManager.unregisterTrafficStateCallback(callback) } + conflatedCallbackFlow { + val callback = TrafficStateCallback { state -> + logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state)) + trySend(state.toWifiDataActivityModel()) } + wifiManager.registerTrafficStateCallback(mainExecutor, callback) + awaitClose { wifiManager.unregisterTrafficStateCallback(callback) } } - .logDiffsForTable( - wifiTableLogBuffer, - columnPrefix = ACTIVITY_PREFIX, - initialValue = ACTIVITY_DEFAULT, - ) - .stateIn( - scope, - started = SharingStarted.WhileSubscribed(), - initialValue = ACTIVITY_DEFAULT - ) + .logDiffsForTable( + wifiTableLogBuffer, + columnPrefix = ACTIVITY_PREFIX, + initialValue = ACTIVITY_DEFAULT, + ) + .stateIn( + scope, + started = SharingStarted.WhileSubscribed(), + initialValue = ACTIVITY_DEFAULT, + ) companion object { private const val ACTIVITY_PREFIX = "wifiActivity" @@ -271,19 +258,19 @@ class WifiRepositoryImpl @Inject constructor( wifiInfo: WifiInfo, network: Network, networkCapabilities: NetworkCapabilities, - wifiManager: WifiManager?, + wifiManager: WifiManager, ): WifiNetworkModel { return if (wifiInfo.isCarrierMerged) { WifiNetworkModel.CarrierMerged } else { WifiNetworkModel.Active( - network.getNetId(), - isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED), - level = wifiManager?.calculateSignalLevel(wifiInfo.rssi), - wifiInfo.ssid, - wifiInfo.isPasspointAp, - wifiInfo.isOsuAp, - wifiInfo.passpointProviderFriendlyName + network.getNetId(), + isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED), + level = wifiManager.calculateSignalLevel(wifiInfo.rssi), + wifiInfo.ssid, + wifiInfo.isPasspointAp, + wifiInfo.isOsuAp, + wifiInfo.passpointProviderFriendlyName ) } } @@ -308,4 +295,28 @@ class WifiRepositoryImpl @Inject constructor( private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel" } + + @SysUISingleton + class Factory + @Inject + constructor( + private val broadcastDispatcher: BroadcastDispatcher, + private val connectivityManager: ConnectivityManager, + private val logger: ConnectivityPipelineLogger, + @WifiTableLog private val wifiTableLogBuffer: TableLogBuffer, + @Main private val mainExecutor: Executor, + @Application private val scope: CoroutineScope, + ) { + fun create(wifiManager: WifiManager): WifiRepositoryImpl { + return WifiRepositoryImpl( + broadcastDispatcher, + connectivityManager, + logger, + wifiTableLogBuffer, + mainExecutor, + scope, + wifiManager, + ) + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt index 93041ceb42008..980560ab5d581 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt @@ -65,6 +65,7 @@ class WifiInteractorImpl @Inject constructor( override val ssid: Flow = wifiRepository.wifiNetwork.map { info -> when (info) { + is WifiNetworkModel.Unavailable -> null is WifiNetworkModel.Inactive -> null is WifiNetworkModel.CarrierMerged -> null is WifiNetworkModel.Active -> when { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt index ab464cc789056..824b5972ba4be 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt @@ -82,6 +82,7 @@ constructor( /** Returns the icon to use based on the given network. */ private fun WifiNetworkModel.icon(): WifiIcon { return when (this) { + is WifiNetworkModel.Unavailable -> WifiIcon.Hidden is WifiNetworkModel.CarrierMerged -> WifiIcon.Hidden is WifiNetworkModel.Inactive -> WifiIcon.Visible( res = WIFI_NO_NETWORK, @@ -89,27 +90,23 @@ constructor( "${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}" ) ) - is WifiNetworkModel.Active -> - when (this.level) { - null -> WifiIcon.Hidden - else -> { - val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level]) - when { - this.isValidated -> - WifiIcon.Visible( - WIFI_FULL_ICONS[this.level], - ContentDescription.Loaded(levelDesc) - ) - else -> - WifiIcon.Visible( - WIFI_NO_INTERNET_ICONS[this.level], - ContentDescription.Loaded( - "$levelDesc,${context.getString(NO_INTERNET)}" - ) - ) - } - } + is WifiNetworkModel.Active -> { + val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level]) + when { + this.isValidated -> + WifiIcon.Visible( + WIFI_FULL_ICONS[this.level], + ContentDescription.Loaded(levelDesc), + ) + else -> + WifiIcon.Visible( + WIFI_NO_INTERNET_ICONS[this.level], + ContentDescription.Loaded( + "$levelDesc,${context.getString(NO_INTERNET)}" + ), + ) } + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt index 30fd308433e44..30ac8d432e8ac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModelTest.kt @@ -34,12 +34,6 @@ class WifiNetworkModelTest : SysuiTestCase() { } } - @Test - fun active_levelNull_noException() { - WifiNetworkModel.Active(NETWORK_ID, level = null) - // No assert, just need no crash - } - @Test(expected = IllegalArgumentException::class) fun active_levelNegative_exceptionThrown() { WifiNetworkModel.Active(NETWORK_ID, level = MIN_VALID_LEVEL - 1) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt new file mode 100644 index 0000000000000..3c4e85bd231eb --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod + +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel +import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test + +@SmallTest +class DisabledWifiRepositoryTest : SysuiTestCase() { + + private lateinit var underTest: DisabledWifiRepository + + @Before + fun setUp() { + underTest = DisabledWifiRepository() + } + + @Test + fun enabled_alwaysFalse() { + assertThat(underTest.isWifiEnabled.value).isEqualTo(false) + } + + @Test + fun default_alwaysFalse() { + assertThat(underTest.isWifiDefault.value).isEqualTo(false) + } + + @Test + fun network_alwaysUnavailable() { + assertThat(underTest.wifiNetwork.value).isEqualTo(WifiNetworkModel.Unavailable) + } + + @Test + fun activity_alwaysFalse() { + assertThat(underTest.wifiActivity.value) + .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt index befb2901d4d5f..8f07615b19b28 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt @@ -33,7 +33,6 @@ import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel -import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any @@ -97,13 +96,6 @@ class WifiRepositoryImplTest : SysuiTestCase() { scope.cancel() } - @Test - fun isWifiEnabled_nullWifiManager_getsFalse() = runBlocking(IMMEDIATE) { - underTest = createRepo(wifiManagerToUse = null) - - assertThat(underTest.isWifiEnabled.value).isFalse() - } - @Test fun isWifiEnabled_initiallyGetsWifiManagerValue() = runBlocking(IMMEDIATE) { whenever(wifiManager.isWifiEnabled).thenReturn(true) @@ -720,21 +712,6 @@ class WifiRepositoryImplTest : SysuiTestCase() { job2.cancel() } - @Test - fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) { - underTest = createRepo(wifiManagerToUse = null) - - var latest: DataActivityModel? = null - val job = underTest - .wifiActivity - .onEach { latest = it } - .launchIn(this) - - assertThat(latest).isEqualTo(ACTIVITY_DEFAULT) - - job.cancel() - } - @Test fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) { var latest: DataActivityModel? = null @@ -801,7 +778,7 @@ class WifiRepositoryImplTest : SysuiTestCase() { job.cancel() } - private fun createRepo(wifiManagerToUse: WifiManager? = wifiManager): WifiRepositoryImpl { + private fun createRepo(): WifiRepositoryImpl { return WifiRepositoryImpl( broadcastDispatcher, connectivityManager, @@ -809,7 +786,7 @@ class WifiRepositoryImplTest : SysuiTestCase() { tableLogger, executor, scope, - wifiManagerToUse, + wifiManager, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt index 2ecb17b7fae0d..01d59f96c2219 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt @@ -51,6 +51,22 @@ class WifiInteractorImplTest : SysuiTestCase() { underTest = WifiInteractorImpl(connectivityRepository, wifiRepository) } + @Test + fun ssid_unavailableNetwork_outputsNull() = + runBlocking(IMMEDIATE) { + wifiRepository.setWifiNetwork(WifiNetworkModel.Unavailable) + + var latest: String? = "default" + val job = underTest + .ssid + .onEach { latest = it } + .launchIn(this) + + assertThat(latest).isNull() + + job.cancel() + } + @Test fun ssid_inactiveNetwork_outputsNull() = runBlocking(IMMEDIATE) { wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) @@ -85,6 +101,7 @@ class WifiInteractorImplTest : SysuiTestCase() { fun ssid_isPasspointAccessPoint_outputsPasspointName() = runBlocking(IMMEDIATE) { wifiRepository.setWifiNetwork(WifiNetworkModel.Active( networkId = 1, + level = 1, isPasspointAccessPoint = true, passpointProviderFriendlyName = "friendly", )) @@ -104,6 +121,7 @@ class WifiInteractorImplTest : SysuiTestCase() { fun ssid_isOnlineSignUpForPasspoint_outputsPasspointName() = runBlocking(IMMEDIATE) { wifiRepository.setWifiNetwork(WifiNetworkModel.Active( networkId = 1, + level = 1, isOnlineSignUpForPasspointAccessPoint = true, passpointProviderFriendlyName = "friendly", )) @@ -123,6 +141,7 @@ class WifiInteractorImplTest : SysuiTestCase() { fun ssid_unknownSsid_outputsNull() = runBlocking(IMMEDIATE) { wifiRepository.setWifiNetwork(WifiNetworkModel.Active( networkId = 1, + level = 1, ssid = WifiManager.UNKNOWN_SSID, )) @@ -141,6 +160,7 @@ class WifiInteractorImplTest : SysuiTestCase() { fun ssid_validSsid_outputsSsid() = runBlocking(IMMEDIATE) { wifiRepository.setWifiNetwork(WifiNetworkModel.Active( networkId = 1, + level = 1, ssid = "MyAwesomeWifiNetwork", )) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt index 12b93819fc5ec..726e813ec4141 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt @@ -379,6 +379,12 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase expected = null, ), + // network = Unavailable => not shown + TestCase( + network = WifiNetworkModel.Unavailable, + expected = null, + ), + // network = Active & validated = false => not shown TestCase( network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 3), @@ -397,12 +403,6 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase description = "Full internet level 4 icon", ), ), - - // network has null level => not shown - TestCase( - network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = null), - expected = null, - ), ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt index 41584347c0f24..e5cfec9c08c02 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt @@ -228,7 +228,7 @@ class WifiViewModelTest : SysuiTestCase() { whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) createAndSetViewModel() - wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null)) + wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null, level = 1)) var activityIn: Boolean? = null val activityInJob = underTest @@ -553,7 +553,8 @@ class WifiViewModelTest : SysuiTestCase() { companion object { private const val NETWORK_ID = 2 - private val ACTIVE_VALID_WIFI_NETWORK = WifiNetworkModel.Active(NETWORK_ID, ssid = "AB") + private val ACTIVE_VALID_WIFI_NETWORK = + WifiNetworkModel.Active(NETWORK_ID, ssid = "AB", level = 1) } } From 7a6bbb6f2608fb6dc8025444b0f7688d54d117d1 Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Wed, 28 Dec 2022 17:32:43 +0000 Subject: [PATCH 2/5] [SB Refactor] Run the linter on WifiRepositoryImpl. Bug: 238425913 Test: atest WifiRepositoryImplTest Change-Id: I873e57bff94c775a06084098d47ff716211d811a --- packages/SystemUI/ktfmt_includes.txt | 1 - .../repository/prod/WifiRepositoryImpl.kt | 224 +++++++++--------- 2 files changed, 116 insertions(+), 109 deletions(-) diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt index 434f227d89c8f..bda396faca60b 100644 --- a/packages/SystemUI/ktfmt_includes.txt +++ b/packages/SystemUI/ktfmt_includes.txt @@ -460,7 +460,6 @@ -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt --packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt index 219fa839a2abf..c47c20d280c7d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt @@ -64,7 +64,9 @@ import kotlinx.coroutines.flow.stateIn @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton @SuppressLint("MissingPermission") -class WifiRepositoryImpl @Inject constructor( +class WifiRepositoryImpl +@Inject +constructor( broadcastDispatcher: BroadcastDispatcher, connectivityManager: ConnectivityManager, logger: ConnectivityPipelineLogger, @@ -74,10 +76,10 @@ class WifiRepositoryImpl @Inject constructor( wifiManager: WifiManager, ) : RealWifiRepository { - private val wifiStateChangeEvents: Flow = broadcastDispatcher.broadcastFlow( - IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION) - ) - .logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent") + private val wifiStateChangeEvents: Flow = + broadcastDispatcher + .broadcastFlow(IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)) + .logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent") private val wifiNetworkChangeEvents: MutableSharedFlow = MutableSharedFlow(extraBufferCapacity = 1) @@ -101,112 +103,118 @@ class WifiRepositoryImpl @Inject constructor( initialValue = wifiManager.isWifiEnabled, ) - override val isWifiDefault: StateFlow = conflatedCallbackFlow { - // Note: This callback doesn't do any logging because we already log every network change - // in the [wifiNetwork] callback. - val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) { - override fun onCapabilitiesChanged( - network: Network, - networkCapabilities: NetworkCapabilities - ) { - // This method will always be called immediately after the network becomes the - // default, in addition to any time the capabilities change while the network is - // the default. - // If this network contains valid wifi info, then wifi is the default network. - val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities) - trySend(wifiInfo != null) + override val isWifiDefault: StateFlow = + conflatedCallbackFlow { + // Note: This callback doesn't do any logging because we already log every network + // change in the [wifiNetwork] callback. + val callback = + object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) { + override fun onCapabilitiesChanged( + network: Network, + networkCapabilities: NetworkCapabilities + ) { + // This method will always be called immediately after the network + // becomes the default, in addition to any time the capabilities change + // while the network is the default. + // If this network contains valid wifi info, then wifi is the default + // network. + val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities) + trySend(wifiInfo != null) + } + + override fun onLost(network: Network) { + // The system no longer has a default network, so wifi is definitely not + // default. + trySend(false) + } + } + + connectivityManager.registerDefaultNetworkCallback(callback) + awaitClose { connectivityManager.unregisterNetworkCallback(callback) } } + .distinctUntilChanged() + .logDiffsForTable( + wifiTableLogBuffer, + columnPrefix = "", + columnName = "isWifiDefault", + initialValue = false, + ) + .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false) - override fun onLost(network: Network) { - // The system no longer has a default network, so wifi is definitely not default. - trySend(false) + override val wifiNetwork: StateFlow = + conflatedCallbackFlow { + var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT + + val callback = + object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) { + override fun onCapabilitiesChanged( + network: Network, + networkCapabilities: NetworkCapabilities + ) { + logger.logOnCapabilitiesChanged(network, networkCapabilities) + + wifiNetworkChangeEvents.tryEmit(Unit) + + val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities) + if (wifiInfo?.isPrimary == true) { + val wifiNetworkModel = + createWifiNetworkModel( + wifiInfo, + network, + networkCapabilities, + wifiManager, + ) + logger.logTransformation( + WIFI_NETWORK_CALLBACK_NAME, + oldValue = currentWifi, + newValue = wifiNetworkModel, + ) + currentWifi = wifiNetworkModel + trySend(wifiNetworkModel) + } + } + + override fun onLost(network: Network) { + logger.logOnLost(network) + + wifiNetworkChangeEvents.tryEmit(Unit) + + val wifi = currentWifi + if ( + wifi is WifiNetworkModel.Active && + wifi.networkId == network.getNetId() + ) { + val newNetworkModel = WifiNetworkModel.Inactive + logger.logTransformation( + WIFI_NETWORK_CALLBACK_NAME, + oldValue = wifi, + newValue = newNetworkModel, + ) + currentWifi = newNetworkModel + trySend(newNetworkModel) + } + } + } + + connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback) + + awaitClose { connectivityManager.unregisterNetworkCallback(callback) } } - } - - connectivityManager.registerDefaultNetworkCallback(callback) - awaitClose { connectivityManager.unregisterNetworkCallback(callback) } - } - .distinctUntilChanged() - .logDiffsForTable( - wifiTableLogBuffer, - columnPrefix = "", - columnName = "isWifiDefault", - initialValue = false, - ) - .stateIn( - scope, - started = SharingStarted.WhileSubscribed(), - initialValue = false - ) - - override val wifiNetwork: StateFlow = conflatedCallbackFlow { - var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT - - val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) { - override fun onCapabilitiesChanged( - network: Network, - networkCapabilities: NetworkCapabilities - ) { - logger.logOnCapabilitiesChanged(network, networkCapabilities) - - wifiNetworkChangeEvents.tryEmit(Unit) - - val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities) - if (wifiInfo?.isPrimary == true) { - val wifiNetworkModel = createWifiNetworkModel( - wifiInfo, - network, - networkCapabilities, - wifiManager, - ) - logger.logTransformation( - WIFI_NETWORK_CALLBACK_NAME, - oldValue = currentWifi, - newValue = wifiNetworkModel - ) - currentWifi = wifiNetworkModel - trySend(wifiNetworkModel) - } - } - - override fun onLost(network: Network) { - logger.logOnLost(network) - - wifiNetworkChangeEvents.tryEmit(Unit) - - val wifi = currentWifi - if (wifi is WifiNetworkModel.Active && wifi.networkId == network.getNetId()) { - val newNetworkModel = WifiNetworkModel.Inactive - logger.logTransformation( - WIFI_NETWORK_CALLBACK_NAME, - oldValue = wifi, - newValue = newNetworkModel - ) - currentWifi = newNetworkModel - trySend(newNetworkModel) - } - } - } - - connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback) - - awaitClose { connectivityManager.unregisterNetworkCallback(callback) } - } - .distinctUntilChanged() - .logDiffsForTable( - wifiTableLogBuffer, - columnPrefix = "wifiNetwork", - initialValue = WIFI_NETWORK_DEFAULT, - ) - // There will be multiple wifi icons in different places that will frequently - // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures that - // new subscribes will get the latest value immediately upon subscription. Otherwise, the - // views could show stale data. See b/244173280. - .stateIn( - scope, - started = SharingStarted.WhileSubscribed(), - initialValue = WIFI_NETWORK_DEFAULT - ) + .distinctUntilChanged() + .logDiffsForTable( + wifiTableLogBuffer, + columnPrefix = "wifiNetwork", + initialValue = WIFI_NETWORK_DEFAULT, + ) + // There will be multiple wifi icons in different places that will frequently + // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures + // that new subscribes will get the latest value immediately upon subscription. + // Otherwise, the views could show stale data. See b/244173280. + .stateIn( + scope, + started = SharingStarted.WhileSubscribed(), + initialValue = WIFI_NETWORK_DEFAULT, + ) override val wifiActivity: StateFlow = conflatedCallbackFlow { From 3747a4723edec8d89c53c2ff52091680cf8f7bc6 Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Wed, 28 Dec 2022 18:34:22 +0000 Subject: [PATCH 3/5] [SB Refactor] Remove unused `isDefaultDataSubscription` flow. Bug: 238425913 Test: verify mobile icon still works Test: verify mobile demo mode still works Test: all tests in statusbar.pipeline.mobile. Specifically, `MobileConnectionsRepositoryTest#config_subIdChangeEvent_updated` Change-Id: Ia61ebeb0d30fc6616eb917dfaf982ef9d4bd7d57 Change-Id: I01b33b246086583bf071b0c7f1aad47c32dfd8ee --- .../repository/MobileConnectionRepository.kt | 6 ---- .../repository/MobileConnectionsRepository.kt | 4 --- .../repository/MobileRepositorySwitcher.kt | 5 ---- .../demo/DemoMobileConnectionsRepository.kt | 11 ------- .../prod/MobileConnectionRepositoryImpl.kt | 17 ----------- .../prod/MobileConnectionsRepositoryImpl.kt | 23 ++------------- .../FakeMobileConnectionRepository.kt | 7 ----- .../FakeMobileConnectionsRepository.kt | 7 ----- .../prod/MobileConnectionRepositoryTest.kt | 28 ------------------ .../prod/MobileConnectionsRepositoryTest.kt | 29 ------------------- 10 files changed, 3 insertions(+), 134 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt index 40e9ba1a46c73..3cc8ddfb7aa5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository import android.telephony.SubscriptionInfo -import android.telephony.SubscriptionManager import android.telephony.TelephonyCallback import android.telephony.TelephonyManager import com.android.systemui.log.table.TableLogBuffer @@ -54,11 +53,6 @@ interface MobileConnectionRepository { val connectionInfo: Flow /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */ val dataEnabled: StateFlow - /** - * True if this connection represents the default subscription per - * [SubscriptionManager.getDefaultDataSubscriptionId] - */ - val isDefaultDataSubscription: StateFlow /** * See [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber]. This bit only matters if diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt index 498c0b93fce88..97b4c2cadbe58 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository import android.provider.Settings import android.telephony.CarrierConfigManager -import android.telephony.SubscriptionManager import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.MobileMappings import com.android.settingslib.mobile.MobileMappings.Config @@ -38,9 +37,6 @@ interface MobileConnectionsRepository { /** Observable for the subscriptionId of the current mobile data connection */ val activeMobileDataSubscriptionId: StateFlow - /** Tracks [SubscriptionManager.getDefaultDataSubscriptionId] */ - val defaultDataSubId: StateFlow - /** The current connectivity status for the default mobile network connection */ val defaultMobileNetworkConnectivity: StateFlow diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt index db9d24ff7abad..0c8593d60cf5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcher.kt @@ -139,11 +139,6 @@ constructor( override val defaultMobileIconGroup: Flow = activeRepo.flatMapLatest { it.defaultMobileIconGroup } - override val defaultDataSubId: StateFlow = - activeRepo - .flatMapLatest { it.defaultDataSubId } - .stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.defaultDataSubId.value) - override val defaultMobileNetworkConnectivity: StateFlow = activeRepo .flatMapLatest { it.defaultMobileNetworkConnectivity } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt index 0b5f9d5ae59e8..bdb1112f06b06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt @@ -139,14 +139,6 @@ constructor( private fun Map.reverse() = entries.associateBy({ it.value }) { it.key } - // TODO(b/261029387): add a command for this value - override val defaultDataSubId = - activeMobileDataSubscriptionId.stateIn( - scope, - SharingStarted.WhileSubscribed(), - INVALID_SUBSCRIPTION_ID - ) - // TODO(b/261029387): not yet supported override val defaultMobileNetworkConnectivity = MutableStateFlow(MobileConnectivityModel()) @@ -199,7 +191,6 @@ constructor( val connection = getRepoForSubId(subId) // This is always true here, because we split out disabled states at the data-source level connection.dataEnabled.value = true - connection.isDefaultDataSubscription.value = state.dataType != null connection.networkName.value = NetworkNameModel.Derived(state.name) connection.cdmaRoaming.value = state.roaming @@ -281,8 +272,6 @@ class DemoMobileConnectionRepository( override val dataEnabled = MutableStateFlow(true) - override val isDefaultDataSubscription = MutableStateFlow(true) - override val cdmaRoaming = MutableStateFlow(false) override val networkName = MutableStateFlow(NetworkNameModel.Derived("demo network")) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt index 5cfff82253c5a..d27d91bb73b54 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt @@ -78,7 +78,6 @@ class MobileConnectionRepositoryImpl( private val telephonyManager: TelephonyManager, private val globalSettings: GlobalSettings, broadcastDispatcher: BroadcastDispatcher, - defaultDataSubId: StateFlow, globalMobileDataSettingChangedEvent: Flow, mobileMappingsProxy: MobileMappingsProxy, bgDispatcher: CoroutineDispatcher, @@ -284,20 +283,6 @@ class MobileConnectionRepositoryImpl( private fun dataConnectionAllowed(): Boolean = telephonyManager.isDataConnectionAllowed - override val isDefaultDataSubscription: StateFlow = run { - val initialValue = defaultDataSubId.value == subId - defaultDataSubId - .mapLatest { it == subId } - .distinctUntilChanged() - .logDiffsForTable( - mobileLogger, - columnPrefix = "", - columnName = "isDefaultDataSub", - initialValue = initialValue, - ) - .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue) - } - class Factory @Inject constructor( @@ -315,7 +300,6 @@ class MobileConnectionRepositoryImpl( subId: Int, defaultNetworkName: NetworkNameModel, networkNameSeparator: String, - defaultDataSubId: StateFlow, globalMobileDataSettingChangedEvent: Flow, ): MobileConnectionRepository { val mobileLogger = logFactory.create(tableBufferLogName(subId), 100) @@ -328,7 +312,6 @@ class MobileConnectionRepositoryImpl( telephonyManager.createForSubscriptionId(subId), globalSettings, broadcastDispatcher, - defaultDataSubId, globalMobileDataSettingChangedEvent, mobileMappingsProxy, bgDispatcher, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt index d407abeb23150..c88c70064238c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt @@ -35,7 +35,6 @@ import android.telephony.TelephonyCallback import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener import android.telephony.TelephonyManager import androidx.annotation.VisibleForTesting -import com.android.internal.telephony.PhoneConstants import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.MobileMappings.Config import com.android.systemui.R @@ -60,7 +59,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.asExecutor import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged @@ -142,24 +140,10 @@ constructor( .logInputChange(logger, "onActiveDataSubscriptionIdChanged") .stateIn(scope, started = SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID) - private val defaultDataSubIdChangeEvent: MutableSharedFlow = - MutableSharedFlow(extraBufferCapacity = 1) - - override val defaultDataSubId: StateFlow = + private val defaultDataSubIdChangedEvent = broadcastDispatcher - .broadcastFlow( - IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED) - ) { intent, _ -> - intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID) - } - .distinctUntilChanged() + .broadcastFlow(IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) .logInputChange(logger, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED") - .onEach { defaultDataSubIdChangeEvent.tryEmit(Unit) } - .stateIn( - scope, - SharingStarted.WhileSubscribed(), - SubscriptionManager.getDefaultDataSubscriptionId() - ) private val carrierConfigChangedEvent = broadcastDispatcher @@ -167,7 +151,7 @@ constructor( .logInputChange(logger, "ACTION_CARRIER_CONFIG_CHANGED") override val defaultDataSubRatConfig: StateFlow = - merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent) + merge(defaultDataSubIdChangedEvent, carrierConfigChangedEvent) .mapLatest { Config.readConfig(context) } .distinctUntilChanged() .logInputChange(logger, "defaultDataSubRatConfig") @@ -272,7 +256,6 @@ constructor( subId, defaultNetworkName, networkNameSeparator, - defaultDataSubId, globalMobileDataSettingChangedEvent, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt index d6a9ee325b2e0..9f347610cfdb5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt @@ -32,9 +32,6 @@ class FakeMobileConnectionRepository( private val _dataEnabled = MutableStateFlow(true) override val dataEnabled = _dataEnabled - private val _isDefaultDataSubscription = MutableStateFlow(true) - override val isDefaultDataSubscription = _isDefaultDataSubscription - override val cdmaRoaming = MutableStateFlow(false) override val networkName = @@ -47,8 +44,4 @@ class FakeMobileConnectionRepository( fun setDataEnabled(enabled: Boolean) { _dataEnabled.value = enabled } - - fun setIsDefaultDataSubscription(isDefault: Boolean) { - _isDefaultDataSubscription.value = isDefault - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt index 7f93328ee95e1..49d4bdc88c828 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt @@ -57,9 +57,6 @@ class FakeMobileConnectionsRepository( private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID) override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId - private val _defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID) - override val defaultDataSubId = _defaultDataSubId - private val _mobileConnectivity = MutableStateFlow(MobileConnectivityModel()) override val defaultMobileNetworkConnectivity = _mobileConnectivity @@ -84,10 +81,6 @@ class FakeMobileConnectionsRepository( _subscriptions.value = subs } - fun setDefaultDataSubId(id: Int) { - _defaultDataSubId.value = id - } - fun setMobileConnectivity(model: MobileConnectivityModel) { _mobileConnectivity.value = model } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt index c63dd2a2318c8..cb642624c7c63 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt @@ -117,7 +117,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { telephonyManager, globalSettings, fakeBroadcastDispatcher, - connectionsRepo.defaultDataSubId, connectionsRepo.globalMobileDataSettingChangedEvent, mobileMappings, IMMEDIATE, @@ -379,33 +378,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { job.cancel() } - @Test - fun isDefaultDataSubscription_isDefault() = - runBlocking(IMMEDIATE) { - connectionsRepo.setDefaultDataSubId(SUB_1_ID) - - var latest: Boolean? = null - val job = underTest.isDefaultDataSubscription.onEach { latest = it }.launchIn(this) - - assertThat(latest).isTrue() - - job.cancel() - } - - @Test - fun isDefaultDataSubscription_isNotDefault() = - runBlocking(IMMEDIATE) { - // Our subId is SUB_1_ID - connectionsRepo.setDefaultDataSubId(123) - - var latest: Boolean? = null - val job = underTest.isDefaultDataSubscription.onEach { latest = it }.launchIn(this) - - assertThat(latest).isFalse() - - job.cancel() - } - @Test fun isDataConnectionAllowed_subIdSettingUpdate_valueUpdated() = runBlocking(IMMEDIATE) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt index b8cd7a4f6e0a0..0da15e2399323 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt @@ -306,35 +306,6 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { job.cancel() } - @Test - fun testDefaultDataSubId_updatesOnBroadcast() = - runBlocking(IMMEDIATE) { - var latest: Int? = null - val job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this) - - fakeBroadcastDispatcher.registeredReceivers.forEach { receiver -> - receiver.onReceive( - context, - Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED) - .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_2_ID) - ) - } - - assertThat(latest).isEqualTo(SUB_2_ID) - - fakeBroadcastDispatcher.registeredReceivers.forEach { receiver -> - receiver.onReceive( - context, - Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED) - .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID) - ) - } - - assertThat(latest).isEqualTo(SUB_1_ID) - - job.cancel() - } - @Test fun mobileConnectivity_default() { assertThat(underTest.defaultMobileNetworkConnectivity.value) From 1d08a47177f68666e21accbf3c367975ec7ca938 Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Wed, 28 Dec 2022 20:26:08 +0000 Subject: [PATCH 4/5] [SB Refactor] Make `numberOfLevels` a flow at the repo level. The carrier merged logic will need to provide `numberOfLevels` at the repo level, so pre-emptively refactor it there now. Bug: 238425913 Test: `adb shell am broadcast -a com.android.systemui.demo -e command network -e mobile show -e level 4 -e datatype 4g` -> shows full triangle Test: all statusbar.pipeline.mobile tests Change-Id: I7f5bc07b4ff9917b32ffb6e56a1f18dbe181e401 --- .../data/repository/MobileConnectionRepository.kt | 9 +++++++++ .../demo/DemoMobileConnectionsRepository.kt | 3 +++ .../prod/MobileConnectionRepositoryImpl.kt | 8 ++++++++ .../domain/interactor/MobileIconInteractor.kt | 14 +++++++------- .../repository/FakeMobileConnectionRepository.kt | 3 +++ .../prod/MobileConnectionRepositoryTest.kt | 12 ++++++++++++ .../domain/interactor/FakeMobileIconInteractor.kt | 3 ++- .../domain/interactor/MobileIconInteractorTest.kt | 15 +++++++++++++++ 8 files changed, 59 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt index 3cc8ddfb7aa5a..d04996b4d6cee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt @@ -51,6 +51,10 @@ interface MobileConnectionRepository { * listener + model. */ val connectionInfo: Flow + + /** The total number of levels. Used with [SignalDrawable]. */ + val numberOfLevels: StateFlow + /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */ val dataEnabled: StateFlow @@ -64,4 +68,9 @@ interface MobileConnectionRepository { /** The service provider name for this network connection, or the default name */ val networkName: StateFlow + + companion object { + /** The default number of levels to use for [numberOfLevels]. */ + const val DEFAULT_NUM_LEVELS = 4 + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt index bdb1112f06b06..988000dc37870 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository +import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile @@ -270,6 +271,8 @@ class DemoMobileConnectionRepository( ) : MobileConnectionRepository { override val connectionInfo = MutableStateFlow(MobileConnectionModel()) + override val numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS) + override val dataEnabled = MutableStateFlow(true) override val cdmaRoaming = MutableStateFlow(false) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt index d27d91bb73b54..711ff22b609da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt @@ -48,6 +48,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository +import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel @@ -63,6 +64,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach @@ -213,6 +215,12 @@ class MobileConnectionRepositoryImpl( .stateIn(scope, SharingStarted.WhileSubscribed(), state) } + // This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL] + // once it's wired up inside of [CarrierConfigTracker]. + override val numberOfLevels: StateFlow = + flowOf(DEFAULT_NUM_LEVELS) + .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS) + /** Produces whenever the mobile data setting changes for this subId */ private val localMobileDataSettingChangedEvent: Flow = conflatedCallbackFlow { val observer = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt index 31ac7a16a9405..9427c6b9fece2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt @@ -23,12 +23,11 @@ import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Connected import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository +import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel -import com.android.systemui.util.CarrierConfigTracker import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine @@ -171,11 +170,12 @@ class MobileIconInteractorImpl( } .stateIn(scope, SharingStarted.WhileSubscribed(), 0) - /** - * This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL] - * once it's wired up inside of [CarrierConfigTracker] - */ - override val numberOfLevels: StateFlow = MutableStateFlow(4) + override val numberOfLevels: StateFlow = + connectionRepository.numberOfLevels.stateIn( + scope, + SharingStarted.WhileSubscribed(), + connectionRepository.numberOfLevels.value, + ) override val isDataConnected: StateFlow = connectionInfo diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt index 9f347610cfdb5..53cd71f1bdf93 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel +import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import kotlinx.coroutines.flow.MutableStateFlow // TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionRepository @@ -29,6 +30,8 @@ class FakeMobileConnectionRepository( private val _connectionInfo = MutableStateFlow(MobileConnectionModel()) override val connectionInfo = _connectionInfo + override val numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS) + private val _dataEnabled = MutableStateFlow(true) override val dataEnabled = _dataEnabled diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt index cb642624c7c63..4bca9eabc36ee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt @@ -61,6 +61,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository +import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel @@ -402,6 +403,17 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { job.cancel() } + @Test + fun numberOfLevels_isDefault() = + runBlocking(IMMEDIATE) { + var latest: Int? = null + val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this) + + assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS) + + job.cancel() + } + @Test fun `roaming - cdma - queries telephony manager`() = runBlocking(IMMEDIATE) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt index ff72715b281ff..a29146b016680 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt @@ -21,6 +21,7 @@ import com.android.settingslib.SignalIcon import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel +import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import kotlinx.coroutines.flow.MutableStateFlow @@ -65,7 +66,7 @@ class FakeMobileIconInteractor( private val _level = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) override val level = _level - private val _numberOfLevels = MutableStateFlow(4) + private val _numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS) override val numberOfLevels = _numberOfLevels fun setIconGroup(group: SignalIcon.MobileIconGroup) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt index 5abe33523cc6f..85eced3491797 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt @@ -177,6 +177,21 @@ class MobileIconInteractorTest : SysuiTestCase() { job.cancel() } + @Test + fun numberOfLevels_comesFromRepo() = + runBlocking(IMMEDIATE) { + var latest: Int? = null + val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this) + + connectionRepository.numberOfLevels.value = 5 + assertThat(latest).isEqualTo(5) + + connectionRepository.numberOfLevels.value = 4 + assertThat(latest).isEqualTo(4) + + job.cancel() + } + @Test fun iconGroup_three_g() = runBlocking(IMMEDIATE) { From c144becdbc30799b599ae171fe786f70f349b5fd Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Tue, 3 Jan 2023 16:24:03 +0000 Subject: [PATCH 5/5] [SB Refactor] Remove `type` from ResolvedNetworkType. ag/20614195 made `type` obsolete. Bug: 238425913 Test: atest MobileConnectionRepositoryTest Change-Id: Ieb73c357e41836e18c3ad7613a8c772a7becf682 --- .../mobile/data/model/ResolvedNetworkType.kt | 5 ----- .../demo/DemoMobileConnectionsRepository.kt | 4 +--- .../prod/MobileConnectionRepositoryImpl.kt | 2 -- .../prod/MobileConnectionRepositoryTest.kt | 4 ++-- .../interactor/MobileIconInteractorTest.kt | 21 ++++--------------- 5 files changed, 7 insertions(+), 29 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt index dd93541d7c8f7..59603874efdef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/ResolvedNetworkType.kt @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.pipeline.mobile.data.model import android.telephony.Annotation.NetworkType -import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy /** @@ -26,21 +25,17 @@ import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy * methods on [MobileMappingsProxy] to generate an icon lookup key. */ sealed interface ResolvedNetworkType { - @NetworkType val type: Int val lookupKey: String object UnknownNetworkType : ResolvedNetworkType { - override val type: Int = NETWORK_TYPE_UNKNOWN override val lookupKey: String = "unknown" } data class DefaultNetworkType( - @NetworkType override val type: Int, override val lookupKey: String, ) : ResolvedNetworkType data class OverrideNetworkType( - @NetworkType override val type: Int, override val lookupKey: String, ) : ResolvedNetworkType } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt index 988000dc37870..0e164e7ee859d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt @@ -253,15 +253,13 @@ constructor( private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType { val key = mobileMappingsReverseLookup.value[this] ?: "dis" - return DefaultNetworkType(DEMO_NET_TYPE, key) + return DefaultNetworkType(key) } companion object { private const val TAG = "DemoMobileConnectionsRepo" private const val DEFAULT_SUB_ID = 1 - - private const val DEMO_NET_TYPE = 1234 } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt index 711ff22b609da..0fa0fea0bebfa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt @@ -186,14 +186,12 @@ class MobileConnectionRepositoryImpl( OVERRIDE_NETWORK_TYPE_NONE ) { DefaultNetworkType( - telephonyDisplayInfo.networkType, mobileMappingsProxy.toIconKey( telephonyDisplayInfo.networkType ) ) } else { OverrideNetworkType( - telephonyDisplayInfo.overrideNetworkType, mobileMappingsProxy.toIconKeyOverride( telephonyDisplayInfo.overrideNetworkType ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt index 4bca9eabc36ee..d6b8c0dbc59d8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt @@ -319,7 +319,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { val callback = getTelephonyCallbackForType() val type = NETWORK_TYPE_LTE - val expected = DefaultNetworkType(type, mobileMappings.toIconKey(type)) + val expected = DefaultNetworkType(mobileMappings.toIconKey(type)) val ti = mock().also { whenever(it.networkType).thenReturn(type) } callback.onDisplayInfoChanged(ti) @@ -336,7 +336,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { val callback = getTelephonyCallbackForType() val type = OVERRIDE_NETWORK_TYPE_LTE_CA - val expected = OverrideNetworkType(type, mobileMappings.toIconKeyOverride(type)) + val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type)) val ti = mock().also { whenever(it.networkType).thenReturn(type) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt index 85eced3491797..61e13b85db6c7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor import android.telephony.CellSignalStrength -import android.telephony.SubscriptionInfo import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import androidx.test.filters.SmallTest import com.android.settingslib.SignalIcon.MobileIconGroup @@ -34,7 +33,6 @@ import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobi import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.THREE_G import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -197,8 +195,7 @@ class MobileIconInteractorTest : SysuiTestCase() { runBlocking(IMMEDIATE) { connectionRepository.setConnectionInfo( MobileConnectionModel( - resolvedNetworkType = - DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G)) + resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G)) ), ) @@ -215,8 +212,7 @@ class MobileIconInteractorTest : SysuiTestCase() { runBlocking(IMMEDIATE) { connectionRepository.setConnectionInfo( MobileConnectionModel( - resolvedNetworkType = - DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G)) + resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G)) ), ) @@ -227,7 +223,6 @@ class MobileIconInteractorTest : SysuiTestCase() { MobileConnectionModel( resolvedNetworkType = DefaultNetworkType( - FOUR_G, mobileMappingsProxy.toIconKey(FOUR_G), ), ), @@ -245,10 +240,7 @@ class MobileIconInteractorTest : SysuiTestCase() { connectionRepository.setConnectionInfo( MobileConnectionModel( resolvedNetworkType = - OverrideNetworkType( - FIVE_G_OVERRIDE, - mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE) - ) + OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE)) ), ) @@ -266,10 +258,7 @@ class MobileIconInteractorTest : SysuiTestCase() { connectionRepository.setConnectionInfo( MobileConnectionModel( resolvedNetworkType = - DefaultNetworkType( - NETWORK_TYPE_UNKNOWN, - mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN) - ), + DefaultNetworkType(mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)), ), ) @@ -524,8 +513,6 @@ class MobileIconInteractorTest : SysuiTestCase() { private const val CDMA_LEVEL = 2 private const val SUB_1_ID = 1 - private val SUB_1 = - mock().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) } private val DEFAULT_NAME = NetworkNameModel.Default("test default name") private val DERIVED_NAME = NetworkNameModel.Derived("test derived name")