diff options
5 files changed, 72 insertions, 3 deletions
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 31dfb7ea7527..0da84f0bec9c 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 @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor import android.telephony.CarrierConfigManager import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Connected import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository @@ -37,6 +38,9 @@ interface MobileIconInteractor { /** Only true if mobile is the default transport but is not validated, otherwise false */ val isDefaultConnectionFailed: StateFlow<Boolean> + /** True when telephony tells us that the data state is CONNECTED */ + val isDataConnected: StateFlow<Boolean> + // TODO(b/256839546): clarify naming of default vs active /** True if we want to consider the data connection enabled */ val isDefaultDataEnabled: StateFlow<Boolean> @@ -114,4 +118,9 @@ class MobileIconInteractorImpl( * once it's wired up inside of [CarrierConfigTracker] */ override val numberOfLevels: StateFlow<Int> = MutableStateFlow(4) + + override val isDataConnected: StateFlow<Boolean> = + mobileStatusInfo + .mapLatest { subscriptionModel -> subscriptionModel.dataConnectionState == Connected } + .stateIn(scope, SharingStarted.WhileSubscribed(), false) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt index 157b0252779c..7869021c0501 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt @@ -68,10 +68,11 @@ constructor( val networkTypeIcon: Flow<Icon?> = combine( iconInteractor.networkTypeIconGroup, + iconInteractor.isDataConnected, iconInteractor.isDataEnabled, - iconInteractor.isDefaultConnectionFailed - ) { networkTypeIconGroup, isDataEnabled, isFailedConnection -> - if (!isDataEnabled || isFailedConnection) { + iconInteractor.isDefaultConnectionFailed, + ) { networkTypeIconGroup, dataConnected, dataEnabled, failedConnection -> + if (!dataConnected || !dataEnabled || failedConnection) { null } else { val desc = 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 b05a284b864c..3ae7d3ca1c19 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 @@ -31,6 +31,8 @@ class FakeMobileIconInteractor : MobileIconInteractor { private val _isFailedConnection = MutableStateFlow(false) override val isDefaultConnectionFailed = _isFailedConnection + override val isDataConnected = MutableStateFlow(true) + private val _isDataEnabled = MutableStateFlow(true) override val isDataEnabled = _isDataEnabled 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 ddc0bc78db9f..7fc1c0f6272c 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 @@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType @@ -231,6 +232,37 @@ class MobileIconInteractorTest : SysuiTestCase() { job.cancel() } + @Test + fun dataState_connected() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.isDataConnected.onEach { latest = it }.launchIn(this) + + connectionRepository.setMobileSubscriptionModel( + MobileSubscriptionModel(dataConnectionState = DataConnectionState.Connected) + ) + yield() + + assertThat(latest).isTrue() + + job.cancel() + } + + @Test + fun dataState_notConnected() = + runBlocking(IMMEDIATE) { + var latest: Boolean? = null + val job = underTest.isDataConnected.onEach { latest = it }.launchIn(this) + + connectionRepository.setMobileSubscriptionModel( + MobileSubscriptionModel(dataConnectionState = DataConnectionState.Disconnected) + ) + + assertThat(latest).isFalse() + + job.cancel() + } + companion object { private val IMMEDIATE = Dispatchers.Main.immediate diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt index 4eecbb9835ed..d4c2c3f6cc2b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt @@ -51,6 +51,7 @@ class MobileIconViewModelTest : SysuiTestCase() { setIconGroup(THREE_G) setIsEmergencyOnly(false) setNumberOfLevels(4) + isDataConnected.value = true } underTest = MobileIconViewModel(SUB_1_ID, interactor, logger) } @@ -127,6 +128,30 @@ class MobileIconViewModelTest : SysuiTestCase() { } @Test + fun networkType_nullWhenDataDisconnects() = + runBlocking(IMMEDIATE) { + val initial = + Icon.Resource( + THREE_G.dataType, + ContentDescription.Resource(THREE_G.dataContentDescription) + ) + + interactor.setIconGroup(THREE_G) + var latest: Icon? = null + val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this) + + interactor.setIconGroup(THREE_G) + assertThat(latest).isEqualTo(initial) + + interactor.isDataConnected.value = false + yield() + + assertThat(latest).isNull() + + job.cancel() + } + + @Test fun networkType_null_changeToDisabled() = runBlocking(IMMEDIATE) { val expected = |