diff options
17 files changed, 203 insertions, 30 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt index 6feada1c9769..937f333b0065 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt @@ -46,6 +46,8 @@ class FakeHomeStatusBarViewModel( override val isHomeStatusBarAllowedByScene = MutableStateFlow(false) + override val shouldHomeStatusBarBeVisible = MutableStateFlow(false) + override val shouldShowOperatorNameView = MutableStateFlow(false) override val isClockVisible = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt index e95bc3378423..be4af868b740 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt @@ -575,6 +575,98 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { } @Test + fun shouldHomeStatusBarBeVisible_keyguardNotGone_noHun_false() = + kosmos.runTest { + // Do not transition from keyguard. i.e., we don't call transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isFalse() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardNotGone_hun_true() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + // there is an active HUN + headsUpNotificationRepository.setNotifications( + UnconfinedFakeHeadsUpRowRepository( + key = "key", + pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser), + ) + ) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isTrue() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardGone_noHun_notInCamera_true() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isTrue() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardGone_hun_notInCamera_true() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + // there is an active HUN + headsUpNotificationRepository.setNotifications( + UnconfinedFakeHeadsUpRowRepository( + key = "key", + pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser), + ) + ) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isTrue() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardGone_noHun_inCamera_false() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.OCCLUDED, + testScope = testScope, + ) + kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isFalse() + } + + @Test fun isClockVisible_allowedByDisableFlags_visible() = kosmos.runTest { val latest by collectLastValue(underTest.isClockVisible) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModelTest.kt index 20cc85f08b01..8608b0bf2f0b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModelTest.kt @@ -39,14 +39,12 @@ class StatusBarOperatorNameViewModelTest : SysuiTestCase() { kosmos.runTest { val intr1 = fakeMobileIconsInteractor.getMobileConnectionInteractorForSubId(1) val intr2 = fakeMobileIconsInteractor.getMobileConnectionInteractorForSubId(2) - val invalidIntr = fakeMobileIconsInteractor.getMobileConnectionInteractorForSubId(-1) // GIVEN default data subId is 1 fakeMobileIconsInteractor.defaultDataSubId.value = 1 intr1.carrierName.value = "Test Name 1" intr2.carrierName.value = "Test Name 2" - invalidIntr.carrierName.value = "default network name" val latest by collectLastValue(underTest.operatorName) @@ -56,8 +54,19 @@ class StatusBarOperatorNameViewModelTest : SysuiTestCase() { assertThat(latest).isEqualTo("Test Name 2") - fakeMobileIconsInteractor.defaultDataSubId.value = -1 + fakeMobileIconsInteractor.defaultDataSubId.value = null - assertThat(latest).isEqualTo("default network name") + assertThat(latest).isNull() + } + + @Test + fun operatorName_noDefaultDataSubId_null() = + kosmos.runTest { + // GIVEN defaultDataSubId is null + fakeMobileIconsInteractor.defaultDataSubId.value = null + + val latest by collectLastValue(underTest.operatorName) + + assertThat(latest).isNull() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt index 057213fa4b18..3c30f3cbec85 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt @@ -25,6 +25,9 @@ object StatusBarRootModernization { /** Aconfig flag for removing the fragment */ const val FLAG_NAME = Flags.FLAG_STATUS_BAR_ROOT_MODERNIZATION + /** Shows a "compose->bar" text in the status bar for debug purposes */ + const val SHOW_DISAMBIGUATION = false + /** A token used for dependency declaration */ val token: FlagToken get() = FlagToken(FLAG_NAME, isEnabled) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt index 30c529a9034a..3e7094a0b5e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt @@ -34,6 +34,9 @@ interface CarrierConfigRepository { */ suspend fun startObservingCarrierConfigUpdates() - /** Gets a cached [SystemUiCarrierConfig], or creates a new one which will track the defaults */ - fun getOrCreateConfigForSubId(subId: Int): SystemUiCarrierConfig + /** + * Gets a cached [SystemUiCarrierConfig], or creates a new one which will track the defaults. A + * null [maybeSubId] will return the default carrier config. + */ + fun getOrCreateConfigForSubId(maybeSubId: Int?): SystemUiCarrierConfig } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt index 9a97f19f6593..b32037992501 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt @@ -20,6 +20,7 @@ import android.content.IntentFilter import android.os.PersistableBundle import android.telephony.CarrierConfigManager import android.telephony.SubscriptionManager +import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import android.util.SparseArray import androidx.annotation.VisibleForTesting import androidx.core.util.getOrElse @@ -51,7 +52,7 @@ constructor( private val defaultConfig: PersistableBundle by lazy { CarrierConfigManager.getDefaultConfig() } // Used for logging the default config in the dumpsys private val defaultConfigForLogs: SystemUiCarrierConfig by lazy { - SystemUiCarrierConfig(-1, defaultConfig) + SystemUiCarrierConfig(INVALID_SUBSCRIPTION_ID, defaultConfig) } private val configs = SparseArray<SystemUiCarrierConfig>() @@ -89,7 +90,10 @@ constructor( configToUpdate.processNewCarrierConfig(config) } - override fun getOrCreateConfigForSubId(subId: Int): SystemUiCarrierConfig { + override fun getOrCreateConfigForSubId(maybeSubId: Int?): SystemUiCarrierConfig { + // See CarrierConfigManager#getConfigForSubId(), passing INVALID_SUBSCRIPTION_ID yields + // the default carrier config + val subId = maybeSubId ?: INVALID_SUBSCRIPTION_ID return configs.getOrElse(subId) { val config = SystemUiCarrierConfig(subId, defaultConfig) val carrierConfig = carrierConfigManager?.getConfigForSubId(subId) 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 32e9c85bea81..09a626940c79 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 @@ -48,8 +48,8 @@ interface MobileConnectionsRepository { */ val activeSubChangedInGroupEvent: Flow<Unit> - /** Tracks [SubscriptionManager.getDefaultDataSubscriptionId] */ - val defaultDataSubId: StateFlow<Int> + /** Tracks [SubscriptionManager.getDefaultDataSubscriptionId]. Null if there is no default */ + val defaultDataSubId: StateFlow<Int?> /** * True if the default network connection is a mobile-like connection and false otherwise. 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 fc766915e4ef..252ebe6a32b0 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 @@ -164,7 +164,7 @@ constructor( override fun getIsAnySimSecure(): Boolean = activeRepo.value.getIsAnySimSecure() - override val defaultDataSubId: StateFlow<Int> = + override val defaultDataSubId: StateFlow<Int?> = activeRepo .flatMapLatest { it.defaultDataSubId } .stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.defaultDataSubId.value) 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 936954f3b484..b608e53b4bce 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 @@ -166,7 +166,7 @@ constructor( private fun <K, V> Map<K, V>.reverse() = entries.associateBy({ it.value }) { it.key } // TODO(b/261029387): add a command for this value - override val defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID) + override val defaultDataSubId: MutableStateFlow<Int?> = MutableStateFlow(null) // TODO(b/261029387): not yet supported override val mobileIsDefault: StateFlow<Boolean> = MutableStateFlow(true) 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 b762751ecbb4..aa6da61958e0 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 @@ -249,7 +249,7 @@ constructor( tableLogger, LOGGING_PREFIX, columnName = "activeSubId", - initialValue = INVALID_SUBSCRIPTION_ID, + initialValue = null, ) .stateIn(scope, started = SharingStarted.WhileSubscribed(), null) @@ -264,22 +264,31 @@ constructor( } .stateIn(scope, SharingStarted.WhileSubscribed(), null) - override val defaultDataSubId: StateFlow<Int> = + override val defaultDataSubId: StateFlow<Int?> = broadcastDispatcher .broadcastFlow( IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED) ) { intent, _ -> - intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID) + val subId = + intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID) + if (subId == INVALID_SUBSCRIPTION_ID) { + null + } else { + subId + } } .distinctUntilChanged() .logDiffsForTable( tableLogger, LOGGING_PREFIX, columnName = "defaultSubId", - initialValue = INVALID_SUBSCRIPTION_ID, + initialValue = null, ) - .onStart { emit(subscriptionManagerProxy.getDefaultDataSubscriptionId()) } - .stateIn(scope, SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID) + .onStart { + val subId = subscriptionManagerProxy.getDefaultDataSubscriptionId() + emit(if (subId == INVALID_SUBSCRIPTION_ID) null else subId) + } + .stateIn(scope, SharingStarted.WhileSubscribed(), null) private val carrierConfigChangedEvent = broadcastDispatcher diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt index 78731faa6167..be56461a96ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt @@ -72,7 +72,7 @@ interface MobileIconsInteractor { val filteredSubscriptions: Flow<List<SubscriptionModel>> /** Subscription ID of the current default data subscription */ - val defaultDataSubId: Flow<Int> + val defaultDataSubId: Flow<Int?> /** * The current list of [MobileIconInteractor]s associated with the current list of diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt index 71e19188f309..b1cc208e9b43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.view.isVisible import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.theme.PlatformTheme @@ -39,6 +40,7 @@ import com.android.keyguard.AlphaOptimizedLinearLayout import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.res.R import com.android.systemui.statusbar.chips.ui.compose.OngoingActivityChips +import com.android.systemui.statusbar.core.StatusBarRootModernization import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips @@ -142,10 +144,14 @@ fun StatusBarRoot( Box(Modifier.fillMaxSize()) { // TODO(b/364360986): remove this before rolling the flag forward - Disambiguation(viewModel = statusBarViewModel) + if (StatusBarRootModernization.SHOW_DISAMBIGUATION) { + Disambiguation(viewModel = statusBarViewModel) + } Row(Modifier.fillMaxSize()) { val scope = rememberCoroutineScope() + val visible = + statusBarViewModel.shouldHomeStatusBarBeVisible.collectAsStateWithLifecycle(false) AndroidView( factory = { context -> val inflater = LayoutInflater.from(context) @@ -280,7 +286,12 @@ fun StatusBarRoot( } onViewCreated(phoneStatusBarView) phoneStatusBarView - } + }, + update = { view -> + // Show or hide the entire status bar. This is important so that we aren't + // visible when first inflated + view.isVisible = visible.value + }, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt index d9d9a29ee2b6..6ff4354fcc46 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt @@ -80,6 +80,9 @@ import kotlinx.coroutines.flow.stateIn * so that it's all in one place and easily testable outside of the fragment. */ interface HomeStatusBarViewModel { + /** Should the entire status bar be hidden? */ + val shouldHomeStatusBarBeVisible: Flow<Boolean> + /** * True if the device is currently transitioning from lockscreen to occluded and false * otherwise. @@ -271,10 +274,12 @@ constructor( isHomeScreenStatusBarAllowedLegacy } - private val shouldHomeStatusBarBeVisible = - combine(isHomeStatusBarAllowed, keyguardInteractor.isSecureCameraActive) { + override val shouldHomeStatusBarBeVisible = + combine( isHomeStatusBarAllowed, - isSecureCameraActive -> + keyguardInteractor.isSecureCameraActive, + headsUpNotificationInteractor.statusBarHeadsUpStatus, + ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState -> // When launching the camera over the lockscreen, the status icons would typically // become visible momentarily before animating out, since we're not yet aware that the // launching camera activity is fullscreen. Even once the activity finishes launching, @@ -282,7 +287,7 @@ constructor( // tells us to hide them. // To ensure that this high-visibility animation is smooth, keep the icons hidden during // a camera launch. See b/257292822. - isHomeStatusBarAllowed && !isSecureCameraActive + headsUpState.isPinned || (isHomeStatusBarAllowed && !isSecureCameraActive) } private val isAnyChipVisible = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModel.kt index 7ae74c3bfb65..0b83c4e3dea3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/StatusBarOperatorNameViewModel.kt @@ -22,6 +22,7 @@ import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf /** * View model for the operator name (aka carrier name) of the carrier for the default data @@ -34,6 +35,10 @@ class StatusBarOperatorNameViewModel constructor(mobileIconsInteractor: MobileIconsInteractor) { val operatorName: Flow<String?> = mobileIconsInteractor.defaultDataSubId.flatMapLatest { - mobileIconsInteractor.getMobileConnectionInteractorForSubId(it).carrierName + if (it == null) { + flowOf(null) + } else { + mobileIconsInteractor.getMobileConnectionInteractorForSubId(it).carrierName + } } } 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 d7456dfb33c3..6c60f55a3904 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 @@ -829,7 +829,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { testScope.runTest { val latest by collectLastValue(underTest.defaultDataSubId) - assertThat(latest).isEqualTo(INVALID_SUBSCRIPTION_ID) + assertThat(latest).isEqualTo(null) val intent2 = Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED) @@ -856,6 +856,31 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { } @Test + fun defaultDataSubId_filtersOutInvalidSubIds() = + testScope.runTest { + subscriptionManagerProxy.defaultDataSubId = INVALID_SUBSCRIPTION_ID + val latest by collectLastValue(underTest.defaultDataSubId) + + assertThat(latest).isNull() + } + + @Test + fun defaultDataSubId_filtersOutInvalidSubIds_fromValidToInvalid() = + testScope.runTest { + subscriptionManagerProxy.defaultDataSubId = 2 + val latest by collectLastValue(underTest.defaultDataSubId) + + assertThat(latest).isEqualTo(2) + + val intent = + Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED) + .putExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID) + fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent) + + assertThat(latest).isNull() + } + + @Test fun defaultDataSubId_fetchesCurrentOnRestart() = testScope.runTest { subscriptionManagerProxy.defaultDataSubId = 2 diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeCarrierConfigRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeCarrierConfigRepository.kt index adf6ca1d1710..eebfca79efe3 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeCarrierConfigRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeCarrierConfigRepository.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository import android.os.PersistableBundle +import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig class FakeCarrierConfigRepository : CarrierConfigRepository { @@ -24,8 +25,12 @@ class FakeCarrierConfigRepository : CarrierConfigRepository { val configsById = mutableMapOf<Int, SystemUiCarrierConfig>() - override fun getOrCreateConfigForSubId(subId: Int): SystemUiCarrierConfig = - configsById.getOrPut(subId) { SystemUiCarrierConfig(subId, createDefaultTestConfig()) } + override fun getOrCreateConfigForSubId(maybeSubId: Int?): SystemUiCarrierConfig { + val subId = maybeSubId ?: INVALID_SUBSCRIPTION_ID + return configsById.getOrPut(subId) { + SystemUiCarrierConfig(subId, createDefaultTestConfig()) + } + } } val CarrierConfigRepository.fake diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt index 3b8adb4a8307..352f6cf011e1 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt @@ -55,7 +55,7 @@ class FakeMobileIconsInteractor( override val filteredSubscriptions = MutableStateFlow<List<SubscriptionModel>>(listOf()) - override val defaultDataSubId = MutableStateFlow(DEFAULT_DATA_SUB_ID) + override val defaultDataSubId: MutableStateFlow<Int?> = MutableStateFlow(DEFAULT_DATA_SUB_ID) private val _activeDataConnectionHasDataEnabled = MutableStateFlow(false) override val activeDataConnectionHasDataEnabled = _activeDataConnectionHasDataEnabled |