Merge changes I02f84f73,I61d6f01c,I6ed7a94b into main

* changes:
  [Networking] Filter out PROFILE_CLASS_PROVISIONING subscriptions
  [Networking] Define FILTER_PRIVISIONING_NETWORK_SUBSCRIPTIONS flag
  [Networking] Add [SubscriptionModel.provisioningClass] field for tracking
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index ff1df36..f4a9f73 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 @@
     // 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 27f6df4..d9d909a 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 @@
 
     /** 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 c7987e2..205dc1c 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 @@
 
 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 @@
                     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 ecb80f2..2caf33b 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 @@
             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 62150e9..dad4093 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 @@
 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 @@
     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 @@
         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 @@
      */
     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 @@
             )
             .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 df38f93..f98267b 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 @@
                 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 4d4f33b..9b6940e 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 @@
 
 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 @@
             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 @@
             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 1c21ebe..787a266 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 @@
 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 @@
             SubscriptionModel(
                 subscriptionId = SUB_ID,
                 carrierName = DEFAULT_NAME,
+                profileClass = PROFILE_CLASS_UNSET,
             )
         )
 
@@ -737,7 +739,7 @@
 
     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 ba64265..a90bd48 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.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 @@
             SubscriptionModel(
                 subscriptionId = SUB_1_ID,
                 carrierName = DEFAULT_NAME,
+                profileClass = PROFILE_CLASS_UNSET,
             )
         )
 
@@ -677,6 +678,7 @@
                 SubscriptionModel(
                     subscriptionId = SUB_1_ID,
                     carrierName = DEFAULT_NAME,
+                    profileClass = PROFILE_CLASS_UNSET,
                 )
 
             assertThat(latest?.name).isEqualTo(DEFAULT_NAME)
@@ -686,6 +688,7 @@
                 SubscriptionModel(
                     subscriptionId = SUB_1_ID,
                     carrierName = updatedName,
+                    profileClass = PROFILE_CLASS_UNSET,
                 )
 
             assertThat(latest?.name).isEqualTo(updatedName)
@@ -980,9 +983,9 @@
     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 18ba6c4..936c58e 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.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 @@
                 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 @@
                 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 @@
             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 @@
             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 @@
             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 e2f9119..20d5c5d 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 @@
             SubscriptionModel(
                 subscriptionId = SUB_1_ID,
                 carrierName = DEFAULT_NAME,
+                profileClass = PROFILE_CLASS_UNSET,
             )
         )
 
@@ -649,9 +651,9 @@
 
         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 b4c7578..2060288 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 @@
     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 @@
                 userSetupRepository,
                 testScope.backgroundScope,
                 context,
+                flags,
             )
     }
 
@@ -318,6 +329,123 @@
         }
 
     @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 @@
                 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 @@
                 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 @@
 
         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 @@
                 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 @@
                 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 1d5487f..6a69d1f 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 @@
     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 @@
                 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 c831e62..b39fc5b 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 @@
     @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 @@
                 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 f3e334e..f029152 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 @@
                         subscriptionId = 1,
                         isOpportunistic = false,
                         carrierName = "Carrier 1",
+                        profileClass = PROFILE_CLASS_UNSET,
                     ),
                 )
             assertThat(latest).isEqualTo(listOf(1))
@@ -112,16 +114,19 @@
                         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 @@
                 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 c935dbb..8405fb4 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.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 @@
     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 @@
                 userSetupRepo,
                 testScope.backgroundScope,
                 context,
+                flags,
             )
 
         underTest =