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 828bb43bb05dd..e0d156aa25f37 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,6 +18,7 @@ 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 @@ -43,6 +44,9 @@ interface MobileConnectionsRepository { */ val activeSubChangedInGroupEvent: Flow + /** 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 164da3b390a72..b93985604fb3e 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 @@ -142,6 +142,11 @@ 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 31a09c6449826..1fcc727e8ad83 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 @@ -152,6 +152,9 @@ constructor( private fun Map.reverse() = entries.associateBy({ it.value }) { it.key } + // TODO(b/261029387): add a command for this value + override val defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID) + // TODO(b/261029387): not yet supported override val defaultMobileNetworkConnectivity = MutableStateFlow(MobileConnectivityModel()) @@ -233,6 +236,9 @@ constructor( val connection = getRepoForSubId(subId) connectionRepoCache[subId]?.lastMobileState = state + // TODO(b/261029387): until we have a command, use the most recent subId + defaultDataSubId.value = subId + // This is always true here, because we split out disabled states at the data-source level connection.dataEnabled.value = true connection.networkName.value = NetworkNameModel.Derived(state.name) 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 29affcf381448..510482dcb21e0 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,6 +35,7 @@ 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 @@ -61,6 +62,7 @@ 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 @@ -162,10 +164,24 @@ constructor( .logInputChange(logger, "onActiveDataSubscriptionIdChanged") .stateIn(scope, started = SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID) - private val defaultDataSubIdChangedEvent = + private val defaultDataSubIdChangeEvent: MutableSharedFlow = + MutableSharedFlow(extraBufferCapacity = 1) + + override val defaultDataSubId: StateFlow = broadcastDispatcher - .broadcastFlow(IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) + .broadcastFlow( + IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED) + ) { intent, _ -> + intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID) + } + .distinctUntilChanged() .logInputChange(logger, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED") + .onEach { defaultDataSubIdChangeEvent.tryEmit(Unit) } + .stateIn( + scope, + SharingStarted.WhileSubscribed(), + SubscriptionManager.getDefaultDataSubscriptionId() + ) private val carrierConfigChangedEvent = broadcastDispatcher @@ -173,7 +189,7 @@ constructor( .logInputChange(logger, "ACTION_CARRIER_CONFIG_CHANGED") override val defaultDataSubRatConfig: StateFlow = - merge(defaultDataSubIdChangedEvent, carrierConfigChangedEvent) + merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent) .mapLatest { Config.readConfig(context) } .distinctUntilChanged() .logInputChange(logger, "defaultDataSubRatConfig") 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 3acada492bf2e..0add905e2750c 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 @@ -59,6 +59,9 @@ class FakeMobileConnectionsRepository( override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId override val activeSubChangedInGroupEvent: MutableSharedFlow = MutableSharedFlow() + private val _defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID) + override val defaultDataSubId = _defaultDataSubId + private val _mobileConnectivity = MutableStateFlow(MobileConnectivityModel()) override val defaultMobileNetworkConnectivity = _mobileConnectivity @@ -83,6 +86,10 @@ 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/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt index 813b0ed041a75..ae390a0e29591 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 @@ -478,6 +478,35 @@ 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)