diff options
16 files changed, 288 insertions, 54 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index ff1df3616b3d..f4a9f739d187 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -406,6 +406,10 @@ object Flags { // TODO(b/301610137): Tracking bug @JvmField val NEW_NETWORK_SLICE_UI = unreleasedFlag("new_network_slice_ui", teamfood = true) + // TODO(b/308138154): Tracking bug + val FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS = + releasedFlag("filter_provisioning_network_subscriptions") + // TODO(b/265892345): Tracking Bug val PLUG_IN_STATUS_BAR_CHIP = releasedFlag("plug_in_status_bar_chip") diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt index 27f6df4c26e1..d9d909a49781 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SubscriptionModel.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.model import android.os.ParcelUuid +import android.telephony.SubscriptionManager.ProfileClass /** * SystemUI representation of [SubscriptionInfo]. Currently we only use two fields on the @@ -37,4 +38,7 @@ data class SubscriptionModel( /** Text representing the name for this connection */ val carrierName: String, + + /** Allow us to filter out PROVISIONING profiles. See [SubscriptionInfo.getProfileClass] */ + @ProfileClass val profileClass: Int ) 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 c7987e2f8eb1..205dc1cd66cf 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 @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository.demo import android.content.Context import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import android.util.Log import com.android.settingslib.SignalIcon import com.android.settingslib.mobile.MobileMappings @@ -96,6 +97,7 @@ constructor( subscriptionId = subId, isOpportunistic = false, carrierName = DEFAULT_CARRIER_NAME, + profileClass = PROFILE_CLASS_UNSET, ) .also { subscriptionInfoCache[subId] = it } 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 ecb80f28de3e..2caf33bd92cf 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 @@ -408,6 +408,7 @@ constructor( isOpportunistic = isOpportunistic, groupUuid = groupUuid, carrierName = carrierName.toString(), + profileClass = profileClass, ) companion object { 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 62150e9a1236..dad409316730 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 @@ -19,10 +19,13 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor import android.content.Context import android.telephony.CarrierConfigManager import android.telephony.SubscriptionManager +import android.telephony.SubscriptionManager.PROFILE_CLASS_PROVISIONING import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.statusbar.pipeline.dagger.MobileSummaryLog @@ -121,6 +124,7 @@ constructor( userSetupRepo: UserSetupRepository, @Application private val scope: CoroutineScope, private val context: Context, + private val featureFlagsClassic: FeatureFlagsClassic, ) : MobileIconsInteractor { // Weak reference lookup for created interactors @@ -163,6 +167,20 @@ constructor( mobileConnectionsRepo.subscriptions /** + * Any filtering that we can do based purely on the info of each subscription. Currently this + * only applies the ProfileClass-based filter, but if we need other they can go here + */ + private val subscriptionsBasedFilteredSubs = + unfilteredSubscriptions.map { subs -> applyProvisioningFilter(subs) }.distinctUntilChanged() + + private fun applyProvisioningFilter(subs: List<SubscriptionModel>): List<SubscriptionModel> = + if (!featureFlagsClassic.isEnabled(FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS)) { + subs + } else { + subs.filter { it.profileClass != PROFILE_CLASS_PROVISIONING } + } + + /** * Generally, SystemUI wants to show iconography for each subscription that is listed by * [SubscriptionManager]. However, in the case of opportunistic subscriptions, we want to only * show a single representation of the pair of subscriptions. The docs define opportunistic as: @@ -177,48 +195,15 @@ constructor( */ override val filteredSubscriptions: Flow<List<SubscriptionModel>> = combine( - unfilteredSubscriptions, + subscriptionsBasedFilteredSubs, mobileConnectionsRepo.activeMobileDataSubscriptionId, connectivityRepository.vcnSubId, ) { unfilteredSubs, activeId, vcnSubId -> - // Based on the old logic, - if (unfilteredSubs.size != 2) { - return@combine unfilteredSubs - } - - val info1 = unfilteredSubs[0] - val info2 = unfilteredSubs[1] - - // Filtering only applies to subscriptions in the same group - if (info1.groupUuid == null || info1.groupUuid != info2.groupUuid) { - return@combine unfilteredSubs - } - - // If both subscriptions are primary, show both - if (!info1.isOpportunistic && !info2.isOpportunistic) { - return@combine unfilteredSubs - } - - // NOTE: at this point, we are now returning a single SubscriptionInfo - - // If carrier required, always show the icon of the primary subscription. - // Otherwise, show whichever subscription is currently active for internet. - if (carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) { - // return the non-opportunistic info - return@combine if (info1.isOpportunistic) listOf(info2) else listOf(info1) - } else { - // It's possible for the subId of the VCN to disagree with the active subId in - // cases where the system has tried to switch but found no connection. In these - // scenarios, VCN will always have the subId that we want to use, so use that - // value instead of the activeId reported by telephony - val subIdToKeep = vcnSubId ?: activeId - - return@combine if (info1.subscriptionId == subIdToKeep) { - listOf(info1) - } else { - listOf(info2) - } - } + filterSubsBasedOnOpportunistic( + unfilteredSubs, + activeId, + vcnSubId, + ) } .distinctUntilChanged() .logDiffsForTable( @@ -229,6 +214,51 @@ constructor( ) .stateIn(scope, SharingStarted.WhileSubscribed(), listOf()) + private fun filterSubsBasedOnOpportunistic( + subList: List<SubscriptionModel>, + activeId: Int?, + vcnSubId: Int?, + ): List<SubscriptionModel> { + // Based on the old logic, + if (subList.size != 2) { + return subList + } + + val info1 = subList[0] + val info2 = subList[1] + + // Filtering only applies to subscriptions in the same group + if (info1.groupUuid == null || info1.groupUuid != info2.groupUuid) { + return subList + } + + // If both subscriptions are primary, show both + if (!info1.isOpportunistic && !info2.isOpportunistic) { + return subList + } + + // NOTE: at this point, we are now returning a single SubscriptionInfo + + // If carrier required, always show the icon of the primary subscription. + // Otherwise, show whichever subscription is currently active for internet. + if (carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) { + // return the non-opportunistic info + return if (info1.isOpportunistic) listOf(info2) else listOf(info1) + } else { + // It's possible for the subId of the VCN to disagree with the active subId in + // cases where the system has tried to switch but found no connection. In these + // scenarios, VCN will always have the subId that we want to use, so use that + // value instead of the activeId reported by telephony + val subIdToKeep = vcnSubId ?: activeId + + return if (info1.subscriptionId == subIdToKeep) { + listOf(info1) + } else { + listOf(info2) + } + } + } + /** * Copied from the old pipeline. We maintain a 2s period of time where we will keep the * validated bit from the old active network (A) while data is changing to the new one (B). diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt index df38f936f4f2..f98267b63986 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt @@ -1,5 +1,6 @@ package com.android.systemui.shade.ui.viewmodel +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -151,12 +152,14 @@ class ShadeHeaderViewModelTest : SysuiTestCase() { subscriptionId = 1, isOpportunistic = false, carrierName = "Carrier 1", + profileClass = PROFILE_CLASS_UNSET, ) private val SUB_2 = SubscriptionModel( subscriptionId = 2, isOpportunistic = false, carrierName = "Carrier 2", + profileClass = PROFILE_CLASS_UNSET, ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt index 4d4f33b63f3f..9b6940e14415 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import android.telephony.TelephonyManager import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -249,11 +250,13 @@ class MobileRepositorySwitcherTest : SysuiTestCase() { mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) whenever(it.carrierName).thenReturn(SUB_1_NAME) + whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET) } private val MODEL_1 = SubscriptionModel( subscriptionId = SUB_1_ID, carrierName = SUB_1_NAME, + profileClass = PROFILE_CLASS_UNSET, ) private const val SUB_2_ID = 2 @@ -262,11 +265,13 @@ class MobileRepositorySwitcherTest : SysuiTestCase() { mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) whenever(it.carrierName).thenReturn(SUB_2_NAME) + whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET) } private val MODEL_2 = SubscriptionModel( subscriptionId = SUB_2_ID, carrierName = SUB_2_NAME, + profileClass = PROFILE_CLASS_UNSET, ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt index 1c21ebe05d84..787a26614909 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod import android.net.ConnectivityManager import android.telephony.ServiceState import android.telephony.SignalStrength +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import android.telephony.TelephonyCallback import android.telephony.TelephonyManager import androidx.test.filters.SmallTest @@ -88,6 +89,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { SubscriptionModel( subscriptionId = SUB_ID, carrierName = DEFAULT_NAME, + profileClass = PROFILE_CLASS_UNSET, ) ) @@ -737,7 +739,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { private companion object { const val SUB_ID = 42 - private val DEFAULT_NAME = "default name" + private const val DEFAULT_NAME = "default name" private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME) private const val SEP = "-" private const val BUFFER_SEPARATOR = "|" 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 ba6426586ebd..a90bd48a5bce 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 @@ -32,13 +32,13 @@ import android.telephony.ServiceState import android.telephony.ServiceState.STATE_IN_SERVICE import android.telephony.ServiceState.STATE_OUT_OF_SERVICE import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import android.telephony.TelephonyCallback import android.telephony.TelephonyCallback.DataActivityListener import android.telephony.TelephonyCallback.ServiceStateListener import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE import android.telephony.TelephonyManager -import android.telephony.TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED import android.telephony.TelephonyManager.DATA_ACTIVITY_DORMANT import android.telephony.TelephonyManager.DATA_ACTIVITY_IN import android.telephony.TelephonyManager.DATA_ACTIVITY_INOUT @@ -132,6 +132,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { SubscriptionModel( subscriptionId = SUB_1_ID, carrierName = DEFAULT_NAME, + profileClass = PROFILE_CLASS_UNSET, ) ) @@ -677,6 +678,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { SubscriptionModel( subscriptionId = SUB_1_ID, carrierName = DEFAULT_NAME, + profileClass = PROFILE_CLASS_UNSET, ) assertThat(latest?.name).isEqualTo(DEFAULT_NAME) @@ -686,6 +688,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { SubscriptionModel( subscriptionId = SUB_1_ID, carrierName = updatedName, + profileClass = PROFILE_CLASS_UNSET, ) assertThat(latest?.name).isEqualTo(updatedName) @@ -980,9 +983,9 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { companion object { private const val SUB_1_ID = 1 - private val DEFAULT_NAME = "Fake Mobile Network" + private const val DEFAULT_NAME = "Fake Mobile Network" private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME) - private val SEP = "-" + private const val SEP = "-" private const val SPN = "testSpn" private const val PLMN = "testPlmn" 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 18ba6c4f5d9f..936c58ecaffb 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 @@ -31,6 +31,7 @@ import android.telephony.CarrierConfigManager import android.telephony.SubscriptionInfo import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import android.telephony.TelephonyCallback import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener import android.telephony.TelephonyManager @@ -1223,12 +1224,14 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { whenever(it.subscriptionId).thenReturn(SUB_1_ID) whenever(it.groupUuid).thenReturn(GROUP_1) whenever(it.carrierName).thenReturn(SUB_1_NAME) + whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET) } private val MODEL_1 = SubscriptionModel( subscriptionId = SUB_1_ID, groupUuid = GROUP_1, carrierName = SUB_1_NAME, + profileClass = PROFILE_CLASS_UNSET, ) // Subscription 2 @@ -1240,12 +1243,14 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { whenever(it.subscriptionId).thenReturn(SUB_2_ID) whenever(it.groupUuid).thenReturn(GROUP_2) whenever(it.carrierName).thenReturn(SUB_2_NAME) + whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET) } private val MODEL_2 = SubscriptionModel( subscriptionId = SUB_2_ID, groupUuid = GROUP_2, carrierName = SUB_2_NAME, + profileClass = PROFILE_CLASS_UNSET, ) // Subs 3 and 4 are considered to be in the same group ------------------------------------ @@ -1257,6 +1262,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_3_ID_GROUPED) whenever(it.groupUuid).thenReturn(GROUP_ID_3_4) + whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET) } // Subscription 4 @@ -1265,6 +1271,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_4_ID_GROUPED) whenever(it.groupUuid).thenReturn(GROUP_ID_3_4) + whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET) } // Subs 3 and 4 are considered to be in the same group ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1279,9 +1286,14 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_CM_ID) whenever(it.carrierName).thenReturn(SUB_CM_NAME) + whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET) } private val MODEL_CM = - SubscriptionModel(subscriptionId = SUB_CM_ID, carrierName = SUB_CM_NAME) + SubscriptionModel( + subscriptionId = SUB_CM_ID, + carrierName = SUB_CM_NAME, + profileClass = PROFILE_CLASS_UNSET, + ) private val WIFI_INFO_CM = mock<WifiInfo>().apply { 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 e2f91194cf40..20d5c5de3ffa 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,6 +17,7 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor import android.telephony.CellSignalStrength +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import androidx.test.filters.SmallTest import com.android.settingslib.mobile.MobileIconCarrierIdOverrides @@ -65,6 +66,7 @@ class MobileIconInteractorTest : SysuiTestCase() { SubscriptionModel( subscriptionId = SUB_1_ID, carrierName = DEFAULT_NAME, + profileClass = PROFILE_CLASS_UNSET, ) ) @@ -649,9 +651,9 @@ class MobileIconInteractorTest : SysuiTestCase() { private const val SUB_1_ID = 1 - private val DEFAULT_NAME = "test default name" + private const val DEFAULT_NAME = "test default name" private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME) - private val DERIVED_NAME = "test derived name" + private const val DERIVED_NAME = "test derived name" private val DERIVED_NAME_MODEL = NetworkNameModel.IntentDerived(DERIVED_NAME) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt index b4c7578241e8..2060288c28a4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt @@ -17,10 +17,16 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor import android.os.ParcelUuid +import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID +import android.telephony.SubscriptionManager.PROFILE_CLASS_PROVISIONING +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import androidx.test.filters.SmallTest import com.android.settingslib.mobile.MobileMappings import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.FakeFeatureFlagsClassic +import com.android.systemui.flags.Flags import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository @@ -57,6 +63,10 @@ class MobileIconsInteractorTest : SysuiTestCase() { private lateinit var connectionsRepository: FakeMobileConnectionsRepository private val userSetupRepository = FakeUserSetupRepository() private val mobileMappingsProxy = FakeMobileMappingsProxy() + private val flags = + FakeFeatureFlagsClassic().apply { + set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true) + } private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) @@ -99,6 +109,7 @@ class MobileIconsInteractorTest : SysuiTestCase() { userSetupRepository, testScope.backgroundScope, context, + flags, ) } @@ -318,6 +329,123 @@ class MobileIconsInteractorTest : SysuiTestCase() { } @Test + fun filteredSubscriptions_doesNotFilterProvisioningWhenFlagIsFalse() = + testScope.runTest { + // GIVEN the flag is false + flags.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, false) + + // GIVEN 1 sub that is in PROFILE_CLASS_PROVISIONING + val sub1 = + SubscriptionModel( + subscriptionId = SUB_1_ID, + isOpportunistic = false, + carrierName = "Carrier 1", + profileClass = PROFILE_CLASS_PROVISIONING, + ) + + connectionsRepository.setSubscriptions(listOf(sub1)) + + // WHEN filtering is applied + val latest by collectLastValue(underTest.filteredSubscriptions) + + // THEN the provisioning sub is still present (unfiltered) + assertThat(latest).isEqualTo(listOf(sub1)) + } + + @Test + fun filteredSubscriptions_filtersOutProvisioningSubs() = + testScope.runTest { + val sub1 = + SubscriptionModel( + subscriptionId = SUB_1_ID, + isOpportunistic = false, + carrierName = "Carrier 1", + profileClass = PROFILE_CLASS_UNSET, + ) + val sub2 = + SubscriptionModel( + subscriptionId = SUB_2_ID, + isOpportunistic = false, + carrierName = "Carrier 2", + profileClass = SubscriptionManager.PROFILE_CLASS_PROVISIONING, + ) + + connectionsRepository.setSubscriptions(listOf(sub1, sub2)) + + val latest by collectLastValue(underTest.filteredSubscriptions) + + assertThat(latest).isEqualTo(listOf(sub1)) + } + + /** Note: I'm not sure if this will ever be the case, but we can test it at least */ + @Test + fun filteredSubscriptions_filtersOutProvisioningSubsBeforeOpportunistic() = + testScope.runTest { + // This is a contrived test case, where the active subId is the one that would + // also be filtered by opportunistic filtering. + + // GIVEN grouped, opportunistic subscriptions + val groupUuid = ParcelUuid(UUID.randomUUID()) + val sub1 = + SubscriptionModel( + subscriptionId = 1, + isOpportunistic = true, + groupUuid = groupUuid, + carrierName = "Carrier 1", + profileClass = PROFILE_CLASS_PROVISIONING, + ) + + val sub2 = + SubscriptionModel( + subscriptionId = 2, + isOpportunistic = true, + groupUuid = groupUuid, + carrierName = "Carrier 2", + profileClass = PROFILE_CLASS_UNSET, + ) + + // GIVEN active subId is 1 + connectionsRepository.setSubscriptions(listOf(sub1, sub2)) + connectionsRepository.setActiveMobileDataSubscriptionId(1) + + // THEN filtering of provisioning subs takes place first, and we result in sub2 + + val latest by collectLastValue(underTest.filteredSubscriptions) + + assertThat(latest).isEqualTo(listOf(sub2)) + } + + @Test + fun filteredSubscriptions_groupedPairAndNonProvisioned_groupedFilteringStillHappens() = + testScope.runTest { + // Grouped filtering only happens when the list of subs is length 2. In this case + // we'll show that filtering of provisioning subs happens before, and thus grouped + // filtering happens even though the unfiltered list is length 3 + val (sub1, sub3) = + createSubscriptionPair( + subscriptionIds = Pair(SUB_1_ID, SUB_3_ID), + opportunistic = Pair(true, true), + grouped = true, + ) + + val sub2 = + SubscriptionModel( + subscriptionId = 2, + isOpportunistic = true, + groupUuid = null, + carrierName = "Carrier 2", + profileClass = PROFILE_CLASS_PROVISIONING, + ) + + connectionsRepository.setSubscriptions(listOf(sub1, sub2, sub3)) + connectionsRepository.setActiveMobileDataSubscriptionId(1) + + val latest by collectLastValue(underTest.filteredSubscriptions) + + assertThat(latest).isEqualTo(listOf(sub1)) + } + + @Test fun activeDataConnection_turnedOn() = testScope.runTest { CONNECTION_1.setDataEnabled(true) @@ -806,7 +934,8 @@ class MobileIconsInteractorTest : SysuiTestCase() { subscriptionId = subscriptionIds.first, isOpportunistic = opportunistic.first, groupUuid = groupUuid, - carrierName = "Carrier ${subscriptionIds.first}" + carrierName = "Carrier ${subscriptionIds.first}", + profileClass = PROFILE_CLASS_UNSET, ) val sub2 = @@ -814,7 +943,8 @@ class MobileIconsInteractorTest : SysuiTestCase() { subscriptionId = subscriptionIds.second, isOpportunistic = opportunistic.second, groupUuid = groupUuid, - carrierName = "Carrier ${opportunistic.second}" + carrierName = "Carrier ${opportunistic.second}", + profileClass = PROFILE_CLASS_UNSET, ) return Pair(sub1, sub2) @@ -824,12 +954,20 @@ class MobileIconsInteractorTest : SysuiTestCase() { private const val SUB_1_ID = 1 private val SUB_1 = - SubscriptionModel(subscriptionId = SUB_1_ID, carrierName = "Carrier $SUB_1_ID") + SubscriptionModel( + subscriptionId = SUB_1_ID, + carrierName = "Carrier $SUB_1_ID", + profileClass = PROFILE_CLASS_UNSET, + ) private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID, mock()) private const val SUB_2_ID = 2 private val SUB_2 = - SubscriptionModel(subscriptionId = SUB_2_ID, carrierName = "Carrier $SUB_2_ID") + SubscriptionModel( + subscriptionId = SUB_2_ID, + carrierName = "Carrier $SUB_2_ID", + profileClass = PROFILE_CLASS_UNSET, + ) private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, mock()) private const val SUB_3_ID = 3 @@ -838,7 +976,8 @@ class MobileIconsInteractorTest : SysuiTestCase() { subscriptionId = SUB_3_ID, isOpportunistic = true, groupUuid = ParcelUuid(UUID.randomUUID()), - carrierName = "Carrier $SUB_3_ID" + carrierName = "Carrier $SUB_3_ID", + profileClass = PROFILE_CLASS_UNSET, ) private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, mock()) @@ -848,7 +987,8 @@ class MobileIconsInteractorTest : SysuiTestCase() { subscriptionId = SUB_4_ID, isOpportunistic = true, groupUuid = ParcelUuid(UUID.randomUUID()), - carrierName = "Carrier $SUB_4_ID" + carrierName = "Carrier $SUB_4_ID", + profileClass = PROFILE_CLASS_UNSET, ) private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, mock()) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt index 1d5487f31e55..6a69d1fea993 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt @@ -70,7 +70,11 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { private lateinit var airplaneModeInteractor: AirplaneModeInteractor private val connectivityRepository = FakeConnectivityRepository() - private val flags = FakeFeatureFlagsClassic().also { it.set(Flags.NEW_NETWORK_SLICE_UI, false) } + private val flags = + FakeFeatureFlagsClassic().also { + it.set(Flags.NEW_NETWORK_SLICE_UI, false) + it.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true) + } @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags @Mock private lateinit var constants: ConnectivityConstants @@ -114,6 +118,7 @@ class LocationBasedMobileIconViewModelTest : SysuiTestCase() { FakeUserSetupRepository(), testScope.backgroundScope, context, + flags, ) interactor = 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 c831e62dd709..b39fc5b8fe21 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 @@ -82,7 +82,11 @@ class MobileIconViewModelTest : SysuiTestCase() { @Mock private lateinit var tableLogBuffer: TableLogBuffer @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker - private val flags = FakeFeatureFlagsClassic().also { it.set(Flags.NEW_NETWORK_SLICE_UI, false) } + private val flags = + FakeFeatureFlagsClassic().also { + it.set(Flags.NEW_NETWORK_SLICE_UI, false) + it.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true) + } private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) @@ -120,6 +124,7 @@ class MobileIconViewModelTest : SysuiTestCase() { FakeUserSetupRepository(), testScope.backgroundScope, context, + flags, ) interactor = diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt index f3e334ed8a22..f029152da0fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel +import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.mobile.TelephonyIcons @@ -102,6 +103,7 @@ class MobileIconsViewModelTest : SysuiTestCase() { subscriptionId = 1, isOpportunistic = false, carrierName = "Carrier 1", + profileClass = PROFILE_CLASS_UNSET, ), ) assertThat(latest).isEqualTo(listOf(1)) @@ -112,16 +114,19 @@ class MobileIconsViewModelTest : SysuiTestCase() { subscriptionId = 2, isOpportunistic = false, carrierName = "Carrier 2", + profileClass = PROFILE_CLASS_UNSET, ), SubscriptionModel( subscriptionId = 5, isOpportunistic = true, carrierName = "Carrier 5", + profileClass = PROFILE_CLASS_UNSET, ), SubscriptionModel( subscriptionId = 7, isOpportunistic = true, carrierName = "Carrier 7", + profileClass = PROFILE_CLASS_UNSET, ), ) assertThat(latest).isEqualTo(listOf(2, 5, 7)) @@ -335,18 +340,21 @@ class MobileIconsViewModelTest : SysuiTestCase() { subscriptionId = 1, isOpportunistic = false, carrierName = "Carrier 1", + profileClass = PROFILE_CLASS_UNSET, ) private val SUB_2 = SubscriptionModel( subscriptionId = 2, isOpportunistic = false, carrierName = "Carrier 2", + profileClass = PROFILE_CLASS_UNSET, ) private val SUB_3 = SubscriptionModel( subscriptionId = 3, isOpportunistic = false, carrierName = "Carrier 3", + profileClass = PROFILE_CLASS_UNSET, ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt index c935dbb0ca1c..8405fb43e16a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt @@ -22,6 +22,8 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.common.shared.model.Text import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.FakeFeatureFlagsClassic +import com.android.systemui.flags.Flags import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon import com.android.systemui.res.R @@ -75,6 +77,11 @@ class InternetTileViewModelTest : SysuiTestCase() { private val mobileConnectionRepository = FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer) + private val flags = + FakeFeatureFlagsClassic().also { + it.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true) + } + private val internet = context.getString(R.string.quick_settings_internet_label) @Before @@ -101,6 +108,7 @@ class InternetTileViewModelTest : SysuiTestCase() { userSetupRepo, testScope.backgroundScope, context, + flags, ) underTest = |