diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index b53cb27..5b48566 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -727,6 +727,7 @@
         "TraceurCommon",
         "Traceur-res",
         "aconfig_settings_flags_lib",
+        "kairos",
     ],
 }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairosTest.kt
index f82de7a..80f4b2c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,235 +19,136 @@
 import android.telephony.SubscriptionInfo
 import android.telephony.SubscriptionManager
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
-import android.telephony.TelephonyManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.demoModeController
 import com.android.systemui.demomode.DemoMode
-import com.android.systemui.demomode.DemoModeController
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.log.table.tableLogBufferFactory
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoModeMobileConnectionDataSource
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepositoryKairos
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.validMobileEvent
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
-import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
-import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.kotlinArgumentCaptor
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
-import org.junit.After
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.stub
 
 /**
  * The switcher acts as a dispatcher to either the `prod` or `demo` versions of the repository
  * interface it's switching on. These tests just need to verify that the entire interface properly
  * switches over when the value of `demoMode` changes
  */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileRepositorySwitcherKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
-
-    private lateinit var underTest: MobileRepositorySwitcherKairos
-    private lateinit var realRepo: MobileConnectionsRepositoryImpl
-    private lateinit var demoRepo: DemoMobileConnectionsRepository
-    private lateinit var mobileDataSource: DemoModeMobileConnectionDataSource
-    private lateinit var wifiDataSource: DemoModeWifiDataSource
-    private lateinit var wifiRepository: FakeWifiRepository
-    private lateinit var connectivityRepository: ConnectivityRepository
-
-    @Mock private lateinit var subscriptionManager: SubscriptionManager
-    @Mock private lateinit var telephonyManager: TelephonyManager
-    @Mock private lateinit var logger: MobileInputLogger
-    @Mock private lateinit var summaryLogger: TableLogBuffer
-    @Mock private lateinit var demoModeController: DemoModeController
-    @Mock private lateinit var dumpManager: DumpManager
-
-    private val fakeNetworkEventsFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
-    private val mobileMappings = FakeMobileMappingsProxy()
-    private val subscriptionManagerProxy = FakeSubscriptionManagerProxy()
-
-    private val scope = CoroutineScope(IMMEDIATE)
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        // Never start in demo mode
-        whenever(demoModeController.isInDemoMode).thenReturn(false)
-
-        mobileDataSource =
-            mock<DemoModeMobileConnectionDataSource>().also {
-                whenever(it.mobileEvents).thenReturn(fakeNetworkEventsFlow)
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            demoModeController.stub {
+                // Never start in demo mode
+                on { isInDemoMode } doReturn false
             }
-        wifiDataSource =
-            mock<DemoModeWifiDataSource>().also {
-                whenever(it.wifiEvents).thenReturn(MutableStateFlow(null))
-            }
-        wifiRepository = FakeWifiRepository()
+            wifiDataSource.stub { on { wifiEvents } doReturn MutableStateFlow(null) }
+        }
 
-        connectivityRepository = FakeConnectivityRepository()
+    private val Kosmos.underTest
+        get() = mobileRepositorySwitcherKairos
 
-        realRepo =
-            MobileConnectionsRepositoryImpl(
-                connectivityRepository,
-                subscriptionManager,
-                subscriptionManagerProxy,
-                telephonyManager,
-                logger,
-                summaryLogger,
-                mobileMappings,
-                fakeBroadcastDispatcher,
-                context,
-                /* bgDispatcher = */ IMMEDIATE,
-                scope,
-                /* mainDispatcher = */ IMMEDIATE,
-                FakeAirplaneModeRepository(),
-                wifiRepository,
-                mock(),
-                mock(),
-                mock(),
-            )
+    private val Kosmos.realRepo
+        get() = mobileConnectionsRepositoryKairosImpl
 
-        demoRepo =
-            DemoMobileConnectionsRepository(
-                mobileDataSource = mobileDataSource,
-                wifiDataSource = wifiDataSource,
-                scope = scope,
-                context = context,
-                logFactory = kosmos.tableLogBufferFactory,
-            )
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
-        underTest =
-            MobileRepositorySwitcherKairos(
-                scope = scope,
-                realRepository = realRepo,
-                demoMobileConnectionsRepository = demoRepo,
-                demoModeController = demoModeController,
-            )
-    }
+    @Test
+    fun activeRepoMatchesDemoModeSetting() = runTest {
+        demoModeController.stub { on { isInDemoMode } doReturn false }
 
-    @After
-    fun tearDown() {
-        scope.cancel()
+        val latest by underTest.activeRepo.collectLastValue()
+
+        assertThat(latest).isEqualTo(realRepo)
+
+        startDemoMode()
+
+        assertThat(latest).isInstanceOf(DemoMobileConnectionsRepositoryKairos::class.java)
+
+        finishDemoMode()
+
+        assertThat(latest).isEqualTo(realRepo)
     }
 
     @Test
-    fun activeRepoMatchesDemoModeSetting() =
-        runBlocking(IMMEDIATE) {
-            whenever(demoModeController.isInDemoMode).thenReturn(false)
+    fun subscriptionListUpdatesWhenDemoModeChanges() = runTest {
+        demoModeController.stub { on { isInDemoMode } doReturn false }
 
-            var latest: MobileConnectionsRepository? = null
-            val job = underTest.activeRepo.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEqualTo(realRepo)
-
-            startDemoMode()
-
-            assertThat(latest).isEqualTo(demoRepo)
-
-            finishDemoMode()
-
-            assertThat(latest).isEqualTo(realRepo)
-
-            job.cancel()
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1, SUB_2)
         }
 
-    @Test
-    fun subscriptionListUpdatesWhenDemoModeChanges() =
-        runBlocking(IMMEDIATE) {
-            whenever(demoModeController.isInDemoMode).thenReturn(false)
+        val latest by underTest.subscriptions.collectLastValue()
 
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2))
+        // The real subscriptions has 2 subs
+        getSubscriptionCallback().onSubscriptionsChanged()
 
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
+        assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
 
-            // The real subscriptions has 2 subs
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
+        // Demo mode turns on, and we should see only the demo subscriptions
+        startDemoMode()
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(validMobileEvent(subId = 3))
 
-            assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
+        // Demo mobile connections repository makes arbitrarily-formed subscription info
+        // objects, so just validate the data we care about
+        assertThat(latest).hasSize(1)
+        assertThat(latest!!.first().subscriptionId).isEqualTo(3)
 
-            // Demo mode turns on, and we should see only the demo subscriptions
-            startDemoMode()
-            fakeNetworkEventsFlow.value = validMobileEvent(subId = 3)
+        finishDemoMode()
 
-            // Demo mobile connections repository makes arbitrarily-formed subscription info
-            // objects, so just validate the data we care about
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].subscriptionId).isEqualTo(3)
+        assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
+    }
 
-            finishDemoMode()
-
-            assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
-
-            job.cancel()
-        }
-
-    private fun startDemoMode() {
-        whenever(demoModeController.isInDemoMode).thenReturn(true)
+    private fun KairosTestScope.startDemoMode() {
+        demoModeController.stub { on { isInDemoMode } doReturn true }
         getDemoModeCallback().onDemoModeStarted()
     }
 
-    private fun finishDemoMode() {
-        whenever(demoModeController.isInDemoMode).thenReturn(false)
+    private fun KairosTestScope.finishDemoMode() {
+        demoModeController.stub { on { isInDemoMode } doReturn false }
         getDemoModeCallback().onDemoModeFinished()
     }
 
-    private fun getSubscriptionCallback(): SubscriptionManager.OnSubscriptionsChangedListener {
-        val callbackCaptor =
-            kotlinArgumentCaptor<SubscriptionManager.OnSubscriptionsChangedListener>()
-        verify(subscriptionManager)
-            .addOnSubscriptionsChangedListener(any(), callbackCaptor.capture())
-        return callbackCaptor.value
-    }
+    private fun KairosTestScope.getSubscriptionCallback():
+        SubscriptionManager.OnSubscriptionsChangedListener =
+        argumentCaptor<SubscriptionManager.OnSubscriptionsChangedListener>()
+            .apply {
+                verify(subscriptionManager).addOnSubscriptionsChangedListener(any(), capture())
+            }
+            .lastValue
 
-    private fun getDemoModeCallback(): DemoMode {
-        val captor = kotlinArgumentCaptor<DemoMode>()
-        verify(demoModeController).addCallback(captor.capture())
-        return captor.value
-    }
+    private fun KairosTestScope.getDemoModeCallback(): DemoMode =
+        argumentCaptor<DemoMode>()
+            .apply { verify(demoModeController).addCallback(capture()) }
+            .lastValue
 
     companion object {
-        private val IMMEDIATE = Dispatchers.Main.immediate
-
         private const val SUB_1_ID = 1
         private const val SUB_1_NAME = "Carrier $SUB_1_ID"
-        private val SUB_1 =
-            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 SUB_1: SubscriptionInfo = mock {
+            on { subscriptionId } doReturn SUB_1_ID
+            on { carrierName } doReturn SUB_1_NAME
+            on { profileClass } doReturn PROFILE_CLASS_UNSET
+        }
         private val MODEL_1 =
             SubscriptionModel(
                 subscriptionId = SUB_1_ID,
@@ -257,12 +158,11 @@
 
         private const val SUB_2_ID = 2
         private const val SUB_2_NAME = "Carrier $SUB_2_ID"
-        private val SUB_2 =
-            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 SUB_2: SubscriptionInfo = mock {
+            on { subscriptionId } doReturn SUB_2_ID
+            on { carrierName } doReturn SUB_2_NAME
+            on { profileClass } doReturn PROFILE_CLASS_UNSET
+        }
         private val MODEL_2 =
             SubscriptionModel(
                 subscriptionId = SUB_2_ID,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionKairosParameterizedTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionKairosParameterizedTest.kt
index d2cd227..99cc93d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionKairosParameterizedTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionKairosParameterizedTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,156 +23,116 @@
 import com.android.settingslib.SignalIcon
 import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.log.table.tableLogBufferFactory
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demoMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demoModeMobileConnectionDataSourceKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.wifiDataSource
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.After
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.stub
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
 /**
  * Parameterized test for all of the common values of [FakeNetworkEventModel]. This test simply
- * verifies that passing the given model to [DemoMobileConnectionsRepository] results in the correct
- * flows emitting from the given connection.
+ * verifies that passing the given model to [DemoMobileConnectionsRepositoryKairos] results in the
+ * correct flows emitting from the given connection.
  */
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
 internal class DemoMobileConnectionKairosParameterizedTest(private val testCase: TestCase) :
     SysuiTestCase() {
-    private val kosmos = testKosmos()
 
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private val Kosmos.fakeWifiEventFlow by Fixture { MutableStateFlow<FakeWifiEventModel?>(null) }
 
-    private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
-    private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            wifiDataSource.stub { on { wifiEvents } doReturn fakeWifiEventFlow }
+        }
 
-    private lateinit var connectionsRepo: DemoMobileConnectionsRepositoryKairos
-    private lateinit var underTest: DemoMobileConnectionRepository
-    private lateinit var mockDataSource: DemoModeMobileConnectionDataSource
-    private lateinit var mockWifiDataSource: DemoModeWifiDataSource
-
-    @Before
-    fun setUp() {
-        // The data source only provides one API, so we can mock it with a flow here for convenience
-        mockDataSource =
-            mock<DemoModeMobileConnectionDataSource>().also {
-                whenever(it.mobileEvents).thenReturn(fakeNetworkEventFlow)
-            }
-        mockWifiDataSource =
-            mock<DemoModeWifiDataSource>().also {
-                whenever(it.wifiEvents).thenReturn(fakeWifiEventFlow)
-            }
-
-        connectionsRepo =
-            DemoMobileConnectionsRepositoryKairos(
-                mobileDataSource = mockDataSource,
-                wifiDataSource = mockWifiDataSource,
-                scope = testScope.backgroundScope,
-                context = context,
-                logFactory = kosmos.tableLogBufferFactory,
-            )
-
-        connectionsRepo.startProcessingCommands()
-    }
-
-    @After
-    fun tearDown() {
-        testScope.cancel()
-    }
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
     @Test
-    fun demoNetworkData() =
-        testScope.runTest {
-            val networkModel =
-                FakeNetworkEventModel.Mobile(
-                    level = testCase.level,
-                    dataType = testCase.dataType,
-                    subId = testCase.subId,
-                    carrierId = testCase.carrierId,
-                    inflateStrength = testCase.inflateStrength,
-                    activity = testCase.activity,
-                    carrierNetworkChange = testCase.carrierNetworkChange,
-                    roaming = testCase.roaming,
-                    name = "demo name",
-                    slice = testCase.slice,
-                )
-
-            fakeNetworkEventFlow.value = networkModel
-            underTest = connectionsRepo.getRepoForSubId(subId)
-
-            assertConnection(underTest, networkModel)
-        }
-
-    private fun TestScope.startCollection(conn: DemoMobileConnectionRepository): Job {
-        val job = launch {
-            launch { conn.cdmaLevel.collect {} }
-            launch { conn.primaryLevel.collect {} }
-            launch { conn.dataActivityDirection.collect {} }
-            launch { conn.carrierNetworkChangeActive.collect {} }
-            launch { conn.isRoaming.collect {} }
-            launch { conn.networkName.collect {} }
-            launch { conn.carrierName.collect {} }
-            launch { conn.isEmergencyOnly.collect {} }
-            launch { conn.dataConnectionState.collect {} }
-            launch { conn.hasPrioritizedNetworkCapabilities.collect {} }
-        }
-        return job
+    fun demoNetworkData() = runTest {
+        val underTest by
+            demoMobileConnectionsRepositoryKairos.mobileConnectionsBySubId
+                .map { it[subId] }
+                .collectLastValue()
+        val networkModel =
+            FakeNetworkEventModel.Mobile(
+                level = testCase.level,
+                dataType = testCase.dataType,
+                subId = testCase.subId,
+                carrierId = testCase.carrierId,
+                inflateStrength = testCase.inflateStrength,
+                activity = testCase.activity,
+                carrierNetworkChange = testCase.carrierNetworkChange,
+                roaming = testCase.roaming,
+                name = "demo name",
+                slice = testCase.slice,
+            )
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(networkModel)
+        assertConnection(underTest!!, networkModel)
     }
 
-    private fun TestScope.assertConnection(
-        conn: DemoMobileConnectionRepository,
+    private suspend fun KairosTestScope.assertConnection(
+        conn: DemoMobileConnectionRepositoryKairos,
         model: FakeNetworkEventModel,
     ) {
-        val job = startCollection(underTest)
         when (model) {
             is FakeNetworkEventModel.Mobile -> {
-                assertThat(conn.subId).isEqualTo(model.subId)
-                assertThat(conn.cdmaLevel.value).isEqualTo(model.level)
-                assertThat(conn.primaryLevel.value).isEqualTo(model.level)
-                assertThat(conn.dataActivityDirection.value)
-                    .isEqualTo((model.activity ?: DATA_ACTIVITY_NONE).toMobileDataActivityModel())
-                assertThat(conn.carrierNetworkChangeActive.value)
-                    .isEqualTo(model.carrierNetworkChange)
-                assertThat(conn.isRoaming.value).isEqualTo(model.roaming)
-                assertThat(conn.networkName.value)
-                    .isEqualTo(NetworkNameModel.IntentDerived(model.name))
-                assertThat(conn.carrierName.value)
-                    .isEqualTo(NetworkNameModel.SubscriptionDerived("${model.name} ${model.subId}"))
-                assertThat(conn.hasPrioritizedNetworkCapabilities.value).isEqualTo(model.slice)
-                assertThat(conn.isNonTerrestrial.value).isEqualTo(model.ntn)
+                kairos.transact {
+                    assertThat(conn.subId).isEqualTo(model.subId)
+                    assertThat(conn.cdmaLevel.sample()).isEqualTo(model.level)
+                    assertThat(conn.primaryLevel.sample()).isEqualTo(model.level)
+                    assertThat(conn.dataActivityDirection.sample())
+                        .isEqualTo(
+                            (model.activity ?: DATA_ACTIVITY_NONE).toMobileDataActivityModel()
+                        )
+                    assertThat(conn.carrierNetworkChangeActive.sample())
+                        .isEqualTo(model.carrierNetworkChange)
+                    assertThat(conn.isRoaming.sample()).isEqualTo(model.roaming)
+                    assertThat(conn.networkName.sample())
+                        .isEqualTo(NetworkNameModel.IntentDerived(model.name))
+                    assertThat(conn.carrierName.sample())
+                        .isEqualTo(
+                            NetworkNameModel.SubscriptionDerived("${model.name} ${model.subId}")
+                        )
+                    assertThat(conn.hasPrioritizedNetworkCapabilities.sample())
+                        .isEqualTo(model.slice)
+                    assertThat(conn.isNonTerrestrial.sample()).isEqualTo(model.ntn)
 
-                // TODO(b/261029387): check these once we start handling them
-                assertThat(conn.isEmergencyOnly.value).isFalse()
-                assertThat(conn.isGsm.value).isFalse()
-                assertThat(conn.dataConnectionState.value).isEqualTo(DataConnectionState.Connected)
+                    // TODO(b/261029387): check these once we start handling them
+                    assertThat(conn.isEmergencyOnly.sample()).isFalse()
+                    assertThat(conn.isGsm.sample()).isFalse()
+                    assertThat(conn.dataConnectionState.sample())
+                        .isEqualTo(DataConnectionState.Connected)
+                }
             }
             // MobileDisabled isn't combinatorial in nature, and is tested in
             // DemoMobileConnectionsRepositoryTest.kt
             else -> {}
         }
-
-        job.cancel()
     }
 
     /** Matches [FakeNetworkEventModel] */
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairosTest.kt
index 95cdee0..503d561 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,572 +21,445 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.log.table.tableLogBufferFactory
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
-import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.MobileDisabled
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demoMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demoModeMobileConnectionDataSourceKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.wifiDataSource
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.stub
 
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DemoMobileConnectionsRepositoryKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
 
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private val Kosmos.fakeWifiEventFlow by
+        Kosmos.Fixture { MutableStateFlow<FakeWifiEventModel?>(null) }
 
-    private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
-    private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
+    private val Kosmos.underTest
+        get() = demoMobileConnectionsRepositoryKairos
 
-    private lateinit var underTest: DemoMobileConnectionsRepositoryKairos
-    private lateinit var mobileDataSource: DemoModeMobileConnectionDataSource
-    private lateinit var wifiDataSource: DemoModeWifiDataSource
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            wifiDataSource.stub { on { wifiEvents } doReturn fakeWifiEventFlow }
+        }
 
-    @Before
-    fun setUp() {
-        // The data source only provides one API, so we can mock it with a flow here for convenience
-        mobileDataSource =
-            mock<DemoModeMobileConnectionDataSource>().also {
-                whenever(it.mobileEvents).thenReturn(fakeNetworkEventFlow)
-            }
-        wifiDataSource =
-            mock<DemoModeWifiDataSource>().also {
-                whenever(it.wifiEvents).thenReturn(fakeWifiEventFlow)
-            }
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
-        underTest =
-            DemoMobileConnectionsRepositoryKairos(
-                mobileDataSource = mobileDataSource,
-                wifiDataSource = wifiDataSource,
-                scope = testScope.backgroundScope,
-                context = context,
-                logFactory = kosmos.tableLogBufferFactory,
-            )
-
-        underTest.startProcessingCommands()
+    @Test
+    fun isDefault_defaultsToTrue() = runTest {
+        underTest
+        val isDefault = kairos.transact { underTest.mobileIsDefault.sample() }
+        assertThat(isDefault).isTrue()
     }
 
     @Test
-    fun isDefault_defaultsToTrue() =
-        testScope.runTest {
-            val isDefault = underTest.mobileIsDefault.value
-            assertThat(isDefault).isTrue()
-        }
-
-    @Test
-    fun validated_defaultsToTrue() =
-        testScope.runTest {
-            val isValidated = underTest.defaultConnectionIsValidated.value
-            assertThat(isValidated).isTrue()
-        }
-
-    @Test
-    fun networkEvent_createNewSubscription() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEmpty()
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1)
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].subscriptionId).isEqualTo(1)
-
-            job.cancel()
-        }
-
-    @Test
-    fun wifiCarrierMergedEvent_createNewSubscription() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEmpty()
-
-            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5)
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].subscriptionId).isEqualTo(5)
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkEvent_reusesSubscriptionWhenSameId() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEmpty()
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].subscriptionId).isEqualTo(1)
-
-            // Second network event comes in with the same subId, does not create a new subscription
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 2)
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].subscriptionId).isEqualTo(1)
-
-            job.cancel()
-        }
-
-    @Test
-    fun wifiCarrierMergedEvent_reusesSubscriptionWhenSameId() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEmpty()
-
-            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5, level = 1)
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].subscriptionId).isEqualTo(5)
-
-            // Second network event comes in with the same subId, does not create a new subscription
-            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5, level = 2)
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].subscriptionId).isEqualTo(5)
-
-            job.cancel()
-        }
-
-    @Test
-    fun multipleSubscriptions() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1)
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 2)
-
-            assertThat(latest).hasSize(2)
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileSubscriptionAndCarrierMergedSubscription() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1)
-            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5)
-
-            assertThat(latest).hasSize(2)
-
-            job.cancel()
-        }
-
-    @Test
-    fun multipleMobileSubscriptionsAndCarrierMergedSubscription() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1)
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 2)
-            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 3)
-
-            assertThat(latest).hasSize(3)
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileDisabledEvent_disablesConnection_subIdSpecified_singleConn() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
-
-            fakeNetworkEventFlow.value = MobileDisabled(subId = 1)
-
-            assertThat(latest).hasSize(0)
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileDisabledEvent_disablesConnection_subIdNotSpecified_singleConn() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
-
-            fakeNetworkEventFlow.value = MobileDisabled(subId = null)
-
-            assertThat(latest).hasSize(0)
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileDisabledEvent_disablesConnection_subIdSpecified_multipleConn() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 2, level = 1)
-
-            fakeNetworkEventFlow.value = MobileDisabled(subId = 2)
-
-            assertThat(latest).hasSize(1)
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileDisabledEvent_subIdNotSpecified_multipleConn_ignoresCommand() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 2, level = 1)
-
-            fakeNetworkEventFlow.value = MobileDisabled(subId = null)
-
-            assertThat(latest).hasSize(2)
-
-            job.cancel()
-        }
-
-    @Test
-    fun wifiNetworkUpdatesToDisabled_carrierMergedConnectionRemoved() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 1)
-
-            assertThat(latest).hasSize(1)
-
-            fakeWifiEventFlow.value = FakeWifiEventModel.WifiDisabled
-
-            assertThat(latest).isEmpty()
-
-            job.cancel()
-        }
-
-    @Test
-    fun wifiNetworkUpdatesToActive_carrierMergedConnectionRemoved() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 1)
-
-            assertThat(latest).hasSize(1)
-
-            fakeWifiEventFlow.value =
-                FakeWifiEventModel.Wifi(level = 1, activity = 0, ssid = null, validated = true)
-
-            assertThat(latest).isEmpty()
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileSubUpdatesToCarrierMerged_onlyOneConnection() =
-        testScope.runTest {
-            var latestSubsList: List<SubscriptionModel>? = null
-            var connections: List<DemoMobileConnectionRepository>? = null
-            val job =
-                underTest.subscriptions
-                    .onEach { latestSubsList = it }
-                    .onEach { infos ->
-                        connections =
-                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
-                    }
-                    .launchIn(this)
-
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 3, level = 2)
-            assertThat(latestSubsList).hasSize(1)
-
-            val carrierMergedEvent = validCarrierMergedEvent(subId = 3, level = 1)
-            fakeWifiEventFlow.value = carrierMergedEvent
-            assertThat(latestSubsList).hasSize(1)
-            val connection = connections!!.find { it.subId == 3 }!!
-            assertCarrierMergedConnection(connection, carrierMergedEvent)
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileSubUpdatesToCarrierMergedThenBack_hasOldMobileData() =
-        testScope.runTest {
-            var latestSubsList: List<SubscriptionModel>? = null
-            var connections: List<DemoMobileConnectionRepository>? = null
-            val job =
-                underTest.subscriptions
-                    .onEach { latestSubsList = it }
-                    .onEach { infos ->
-                        connections =
-                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
-                    }
-                    .launchIn(this)
-
-            val mobileEvent = validMobileEvent(subId = 3, level = 2)
-            fakeNetworkEventFlow.value = mobileEvent
-            assertThat(latestSubsList).hasSize(1)
-
-            val carrierMergedEvent = validCarrierMergedEvent(subId = 3, level = 1)
-            fakeWifiEventFlow.value = carrierMergedEvent
-            assertThat(latestSubsList).hasSize(1)
-            var connection = connections!!.find { it.subId == 3 }!!
-            assertCarrierMergedConnection(connection, carrierMergedEvent)
-
-            // WHEN the carrier merged is removed
-            fakeWifiEventFlow.value =
-                FakeWifiEventModel.Wifi(level = 4, activity = 0, ssid = null, validated = true)
-
-            // THEN the subId=3 connection goes back to the mobile information
-            connection = connections!!.find { it.subId == 3 }!!
-            assertConnection(connection, mobileEvent)
-
-            job.cancel()
-        }
-
-    /** Regression test for b/261706421 */
-    @Test
-    fun multipleConnections_removeAll_doesNotThrow() =
-        testScope.runTest {
-            var latest: List<SubscriptionModel>? = null
-            val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
-
-            // Two subscriptions are added
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
-            fakeNetworkEventFlow.value = validMobileEvent(subId = 2, level = 1)
-
-            // Then both are removed by turning off demo mode
-            underTest.stopProcessingCommands()
-
-            assertThat(latest).isEmpty()
-
-            job.cancel()
-        }
-
-    @Test
-    fun demoConnection_singleSubscription() =
-        testScope.runTest {
-            var currentEvent: FakeNetworkEventModel = validMobileEvent(subId = 1)
-            var connections: List<DemoMobileConnectionRepository>? = null
-            val job =
-                underTest.subscriptions
-                    .onEach { infos ->
-                        connections =
-                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
-                    }
-                    .launchIn(this)
-
-            fakeNetworkEventFlow.value = currentEvent
-
-            assertThat(connections).hasSize(1)
-            val connection1 = connections!![0]
-
-            assertConnection(connection1, currentEvent)
-
-            // Exercise the whole api
-
-            currentEvent = validMobileEvent(subId = 1, level = 2)
-            fakeNetworkEventFlow.value = currentEvent
-            assertConnection(connection1, currentEvent)
-
-            job.cancel()
-        }
-
-    @Test
-    fun demoConnection_twoConnections_updateSecond_noAffectOnFirst() =
-        testScope.runTest {
-            var currentEvent1 = validMobileEvent(subId = 1)
-            var connection1: DemoMobileConnectionRepository? = null
-            var currentEvent2 = validMobileEvent(subId = 2)
-            var connection2: DemoMobileConnectionRepository? = null
-            var connections: List<DemoMobileConnectionRepository>? = null
-            val job =
-                underTest.subscriptions
-                    .onEach { infos ->
-                        connections =
-                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
-                    }
-                    .launchIn(this)
-
-            fakeNetworkEventFlow.value = currentEvent1
-            fakeNetworkEventFlow.value = currentEvent2
-            assertThat(connections).hasSize(2)
-            connections!!.forEach {
-                if (it.subId == 1) {
-                    connection1 = it
-                } else if (it.subId == 2) {
-                    connection2 = it
-                } else {
-                    Assert.fail("Unexpected subscription")
-                }
-            }
-
-            assertConnection(connection1!!, currentEvent1)
-            assertConnection(connection2!!, currentEvent2)
-
-            // WHEN the event changes for connection 2, it updates, and connection 1 stays the same
-            currentEvent2 = validMobileEvent(subId = 2, activity = DATA_ACTIVITY_INOUT)
-            fakeNetworkEventFlow.value = currentEvent2
-            assertConnection(connection1!!, currentEvent1)
-            assertConnection(connection2!!, currentEvent2)
-
-            // and vice versa
-            currentEvent1 = validMobileEvent(subId = 1, inflateStrength = true)
-            fakeNetworkEventFlow.value = currentEvent1
-            assertConnection(connection1!!, currentEvent1)
-            assertConnection(connection2!!, currentEvent2)
-
-            job.cancel()
-        }
-
-    @Test
-    fun demoConnection_twoConnections_updateCarrierMerged_noAffectOnFirst() =
-        testScope.runTest {
-            var currentEvent1 = validMobileEvent(subId = 1)
-            var connection1: DemoMobileConnectionRepository? = null
-            var currentEvent2 = validCarrierMergedEvent(subId = 2)
-            var connection2: DemoMobileConnectionRepository? = null
-            var connections: List<DemoMobileConnectionRepository>? = null
-            val job =
-                underTest.subscriptions
-                    .onEach { infos ->
-                        connections =
-                            infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
-                    }
-                    .launchIn(this)
-
-            fakeNetworkEventFlow.value = currentEvent1
-            fakeWifiEventFlow.value = currentEvent2
-            assertThat(connections).hasSize(2)
-            connections!!.forEach {
-                when (it.subId) {
-                    1 -> connection1 = it
-                    2 -> connection2 = it
-                    else -> Assert.fail("Unexpected subscription")
-                }
-            }
-
-            assertConnection(connection1!!, currentEvent1)
-            assertCarrierMergedConnection(connection2!!, currentEvent2)
-
-            // WHEN the event changes for connection 2, it updates, and connection 1 stays the same
-            currentEvent2 = validCarrierMergedEvent(subId = 2, level = 4)
-            fakeWifiEventFlow.value = currentEvent2
-            assertConnection(connection1!!, currentEvent1)
-            assertCarrierMergedConnection(connection2!!, currentEvent2)
-
-            // and vice versa
-            currentEvent1 = validMobileEvent(subId = 1, inflateStrength = true)
-            fakeNetworkEventFlow.value = currentEvent1
-            assertConnection(connection1!!, currentEvent1)
-            assertCarrierMergedConnection(connection2!!, currentEvent2)
-
-            job.cancel()
-        }
-
-    @Test
-    fun demoIsNotInEcmState() = testScope.runTest { assertThat(underTest.isInEcmMode()).isFalse() }
-
-    private fun TestScope.startCollection(conn: DemoMobileConnectionRepository): Job {
-        val job = launch {
-            launch { conn.cdmaLevel.collect {} }
-            launch { conn.primaryLevel.collect {} }
-            launch { conn.dataActivityDirection.collect {} }
-            launch { conn.carrierNetworkChangeActive.collect {} }
-            launch { conn.isRoaming.collect {} }
-            launch { conn.networkName.collect {} }
-            launch { conn.carrierName.collect {} }
-            launch { conn.isEmergencyOnly.collect {} }
-            launch { conn.dataConnectionState.collect {} }
-            launch { conn.hasPrioritizedNetworkCapabilities.collect {} }
-        }
-        return job
+    fun validated_defaultsToTrue() = runTest {
+        underTest
+        val isValidated = kairos.transact { underTest.defaultConnectionIsValidated.sample() }
+        assertThat(isValidated).isTrue()
     }
 
-    private fun TestScope.assertConnection(
-        conn: DemoMobileConnectionRepository,
+    @Test
+    fun networkEvent_createNewSubscription() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        assertThat(latest).isEmpty()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(validMobileEvent(subId = 1))
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!!.first().subscriptionId).isEqualTo(1)
+    }
+
+    @Test
+    fun wifiCarrierMergedEvent_createNewSubscription() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        assertThat(latest).isEmpty()
+
+        fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5)
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!!.first().subscriptionId).isEqualTo(5)
+    }
+
+    @Test
+    fun networkEvent_reusesSubscriptionWhenSameId() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        assertThat(latest).isEmpty()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 1, level = 1)
+        )
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!!.first().subscriptionId).isEqualTo(1)
+
+        // Second network event comes in with the same subId, does not create a new subscription
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 1, level = 2)
+        )
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!!.first().subscriptionId).isEqualTo(1)
+    }
+
+    @Test
+    fun wifiCarrierMergedEvent_reusesSubscriptionWhenSameId() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        assertThat(latest).isEmpty()
+
+        fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5, level = 1)
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!!.first().subscriptionId).isEqualTo(5)
+
+        // Second network event comes in with the same subId, does not create a new subscription
+        fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5, level = 2)
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!!.first().subscriptionId).isEqualTo(5)
+    }
+
+    @Test
+    fun multipleSubscriptions() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(validMobileEvent(subId = 1))
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(validMobileEvent(subId = 2))
+
+        assertThat(latest).hasSize(2)
+    }
+
+    @Test
+    fun mobileSubscriptionAndCarrierMergedSubscription() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(validMobileEvent(subId = 1))
+        fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 5)
+
+        assertThat(latest).hasSize(2)
+    }
+
+    @Test
+    fun multipleMobileSubscriptionsAndCarrierMergedSubscription() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(validMobileEvent(subId = 1))
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(validMobileEvent(subId = 2))
+        fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 3)
+
+        assertThat(latest).hasSize(3)
+    }
+
+    @Test
+    fun mobileDisabledEvent_disablesConnection_subIdSpecified_singleConn() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 1, level = 1)
+        )
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(MobileDisabled(subId = 1))
+
+        assertThat(latest).hasSize(0)
+    }
+
+    @Test
+    fun mobileDisabledEvent_disablesConnection_subIdNotSpecified_singleConn() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 1, level = 1)
+        )
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            MobileDisabled(subId = null)
+        )
+
+        assertThat(latest).hasSize(0)
+    }
+
+    @Test
+    fun mobileDisabledEvent_disablesConnection_subIdSpecified_multipleConn() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 1, level = 1)
+        )
+
+        assertThat(latest).hasSize(1)
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 2, level = 1)
+        )
+
+        assertThat(latest).hasSize(2)
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(MobileDisabled(subId = 2))
+
+        assertThat(latest).hasSize(1)
+    }
+
+    @Test
+    fun mobileDisabledEvent_subIdNotSpecified_multipleConn_ignoresCommand() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 1, level = 1)
+        )
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 2, level = 1)
+        )
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            MobileDisabled(subId = null)
+        )
+
+        assertThat(latest).hasSize(2)
+    }
+
+    @Test
+    fun wifiNetworkUpdatesToDisabled_carrierMergedConnectionRemoved() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 1)
+
+        assertThat(latest).hasSize(1)
+
+        fakeWifiEventFlow.value = FakeWifiEventModel.WifiDisabled
+
+        assertThat(latest).isEmpty()
+    }
+
+    @Test
+    fun wifiNetworkUpdatesToActive_carrierMergedConnectionRemoved() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        fakeWifiEventFlow.value = validCarrierMergedEvent(subId = 1)
+
+        assertThat(latest).hasSize(1)
+
+        fakeWifiEventFlow.value =
+            FakeWifiEventModel.Wifi(level = 1, activity = 0, ssid = null, validated = true)
+
+        assertThat(latest).isEmpty()
+    }
+
+    @Test
+    fun mobileSubUpdatesToCarrierMerged_onlyOneConnection() = runTest {
+        val latestSubsList by underTest.subscriptions.collectLastValue()
+        val connections by underTest.mobileConnectionsBySubId.map { it.values }.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(
+            validMobileEvent(subId = 3, level = 2)
+        )
+        assertThat(latestSubsList).hasSize(1)
+
+        val carrierMergedEvent = validCarrierMergedEvent(subId = 3, level = 1)
+        fakeWifiEventFlow.value = carrierMergedEvent
+        assertThat(latestSubsList).hasSize(1)
+        val connection = connections!!.find { it.subId == 3 }!!
+        assertCarrierMergedConnection(connection, carrierMergedEvent)
+    }
+
+    @Test
+    fun mobileSubUpdatesToCarrierMergedThenBack_hasOldMobileData() = runTest {
+        val latestSubsList by underTest.subscriptions.collectLastValue()
+        val connections by underTest.mobileConnectionsBySubId.map { it.values }.collectLastValue()
+
+        val mobileEvent = validMobileEvent(subId = 3, level = 2)
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(mobileEvent)
+        assertThat(latestSubsList).hasSize(1)
+
+        val carrierMergedEvent = validCarrierMergedEvent(subId = 3, level = 1)
+        fakeWifiEventFlow.value = carrierMergedEvent
+        assertThat(latestSubsList).hasSize(1)
+        var connection = connections!!.find { it.subId == 3 }!!
+        assertCarrierMergedConnection(connection, carrierMergedEvent)
+
+        // WHEN the carrier merged is removed
+        fakeWifiEventFlow.value =
+            FakeWifiEventModel.Wifi(level = 4, activity = 0, ssid = null, validated = true)
+
+        assertThat(latestSubsList).hasSize(1)
+        assertThat(connections).hasSize(1)
+
+        // THEN the subId=3 connection goes back to the mobile information
+        connection = connections!!.find { it.subId == 3 }!!
+        assertConnection(connection, mobileEvent)
+    }
+
+    @Test
+    fun demoConnection_singleSubscription() = runTest {
+        var currentEvent: FakeNetworkEventModel = validMobileEvent(subId = 1)
+        val connections by underTest.mobileConnectionsBySubId.map { it.values }.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent)
+
+        assertThat(connections).hasSize(1)
+        val connection1 = connections!!.first()
+
+        assertConnection(connection1, currentEvent)
+
+        // Exercise the whole api
+
+        currentEvent = validMobileEvent(subId = 1, level = 2)
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent)
+        assertConnection(connection1, currentEvent)
+    }
+
+    @Test
+    fun demoConnection_twoConnections_updateSecond_noAffectOnFirst() = runTest {
+        var currentEvent1 = validMobileEvent(subId = 1)
+        var connection1: DemoMobileConnectionRepositoryKairos? = null
+        var currentEvent2 = validMobileEvent(subId = 2)
+        var connection2: DemoMobileConnectionRepositoryKairos? = null
+        val connections by underTest.mobileConnectionsBySubId.map { it.values }.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent1)
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent2)
+        assertThat(connections).hasSize(2)
+        connections!!.forEach {
+            when (it.subId) {
+                1 -> connection1 = it
+                2 -> connection2 = it
+                else -> Assert.fail("Unexpected subscription")
+            }
+        }
+
+        assertConnection(connection1!!, currentEvent1)
+        assertConnection(connection2!!, currentEvent2)
+
+        // WHEN the event changes for connection 2, it updates, and connection 1 stays the same
+        currentEvent2 = validMobileEvent(subId = 2, activity = DATA_ACTIVITY_INOUT)
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent2)
+        assertConnection(connection1!!, currentEvent1)
+        assertConnection(connection2!!, currentEvent2)
+
+        // and vice versa
+        currentEvent1 = validMobileEvent(subId = 1, inflateStrength = true)
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent1)
+        assertConnection(connection1!!, currentEvent1)
+        assertConnection(connection2!!, currentEvent2)
+    }
+
+    @Test
+    fun demoConnection_twoConnections_updateCarrierMerged_noAffectOnFirst() = runTest {
+        var currentEvent1 = validMobileEvent(subId = 1)
+        var connection1: DemoMobileConnectionRepositoryKairos? = null
+        var currentEvent2 = validCarrierMergedEvent(subId = 2)
+        var connection2: DemoMobileConnectionRepositoryKairos? = null
+        val connections by underTest.mobileConnectionsBySubId.map { it.values }.collectLastValue()
+
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent1)
+        fakeWifiEventFlow.value = currentEvent2
+        assertThat(connections).hasSize(2)
+        connections!!.forEach {
+            when (it.subId) {
+                1 -> connection1 = it
+                2 -> connection2 = it
+                else -> Assert.fail("Unexpected subscription")
+            }
+        }
+
+        assertConnection(connection1!!, currentEvent1)
+        assertCarrierMergedConnection(connection2!!, currentEvent2)
+
+        // WHEN the event changes for connection 2, it updates, and connection 1 stays the same
+        currentEvent2 = validCarrierMergedEvent(subId = 2, level = 4)
+        fakeWifiEventFlow.value = currentEvent2
+        assertConnection(connection1!!, currentEvent1)
+        assertCarrierMergedConnection(connection2!!, currentEvent2)
+
+        // and vice versa
+        currentEvent1 = validMobileEvent(subId = 1, inflateStrength = true)
+        demoModeMobileConnectionDataSourceKairos.fake.mobileEvents.emit(currentEvent1)
+        assertConnection(connection1!!, currentEvent1)
+        assertCarrierMergedConnection(connection2!!, currentEvent2)
+    }
+
+    @Test
+    fun demoIsNotInEcmState() = runTest {
+        underTest
+        assertThat(kairos.transact { underTest.isInEcmMode.sample() }).isFalse()
+    }
+
+    private suspend fun KairosTestScope.assertConnection(
+        conn: DemoMobileConnectionRepositoryKairos,
         model: FakeNetworkEventModel,
     ) {
-        val job = startCollection(conn)
-        // Assert the fields using the `MutableStateFlow` so that we don't have to start up
-        // a collector for every field for every test
         when (model) {
             is FakeNetworkEventModel.Mobile -> {
-                assertThat(conn.subId).isEqualTo(model.subId)
-                assertThat(conn.cdmaLevel.value).isEqualTo(model.level)
-                assertThat(conn.primaryLevel.value).isEqualTo(model.level)
-                assertThat(conn.dataActivityDirection.value)
-                    .isEqualTo((model.activity ?: DATA_ACTIVITY_NONE).toMobileDataActivityModel())
-                assertThat(conn.carrierNetworkChangeActive.value)
-                    .isEqualTo(model.carrierNetworkChange)
-                assertThat(conn.isRoaming.value).isEqualTo(model.roaming)
-                assertThat(conn.networkName.value)
-                    .isEqualTo(NetworkNameModel.IntentDerived(model.name))
-                assertThat(conn.carrierName.value)
-                    .isEqualTo(NetworkNameModel.SubscriptionDerived("${model.name} ${model.subId}"))
-                assertThat(conn.hasPrioritizedNetworkCapabilities.value).isEqualTo(model.slice)
-                assertThat(conn.isNonTerrestrial.value).isEqualTo(model.ntn)
+                kairos.transact {
+                    assertThat(conn.subId).isEqualTo(model.subId)
+                    assertThat(conn.cdmaLevel.sample()).isEqualTo(model.level)
+                    assertThat(conn.primaryLevel.sample()).isEqualTo(model.level)
+                    assertThat(conn.dataActivityDirection.sample())
+                        .isEqualTo(
+                            (model.activity ?: DATA_ACTIVITY_NONE).toMobileDataActivityModel()
+                        )
+                    assertThat(conn.carrierNetworkChangeActive.sample())
+                        .isEqualTo(model.carrierNetworkChange)
+                    assertThat(conn.isRoaming.sample()).isEqualTo(model.roaming)
+                    assertThat(conn.networkName.sample())
+                        .isEqualTo(NetworkNameModel.IntentDerived(model.name))
+                    assertThat(conn.carrierName.sample())
+                        .isEqualTo(
+                            NetworkNameModel.SubscriptionDerived("${model.name} ${model.subId}")
+                        )
+                    assertThat(conn.hasPrioritizedNetworkCapabilities.sample())
+                        .isEqualTo(model.slice)
+                    assertThat(conn.isNonTerrestrial.sample()).isEqualTo(model.ntn)
 
-                // TODO(b/261029387) check these once we start handling them
-                assertThat(conn.isEmergencyOnly.value).isFalse()
-                assertThat(conn.isGsm.value).isFalse()
-                assertThat(conn.dataConnectionState.value).isEqualTo(DataConnectionState.Connected)
+                    // TODO(b/261029387) check these once we start handling them
+                    assertThat(conn.isEmergencyOnly.sample()).isFalse()
+                    assertThat(conn.isGsm.sample()).isFalse()
+                    assertThat(conn.dataConnectionState.sample())
+                        .isEqualTo(DataConnectionState.Connected)
+                }
             }
             else -> {}
         }
-
-        job.cancel()
     }
 
-    private fun TestScope.assertCarrierMergedConnection(
-        conn: DemoMobileConnectionRepository,
+    private suspend fun KairosTestScope.assertCarrierMergedConnection(
+        conn: DemoMobileConnectionRepositoryKairos,
         model: FakeWifiEventModel.CarrierMerged,
     ) {
-        val job = startCollection(conn)
-        assertThat(conn.subId).isEqualTo(model.subscriptionId)
-        assertThat(conn.cdmaLevel.value).isEqualTo(model.level)
-        assertThat(conn.primaryLevel.value).isEqualTo(model.level)
-        assertThat(conn.carrierNetworkChangeActive.value).isEqualTo(false)
-        assertThat(conn.isRoaming.value).isEqualTo(false)
-        assertThat(conn.isEmergencyOnly.value).isFalse()
-        assertThat(conn.isGsm.value).isFalse()
-        assertThat(conn.dataConnectionState.value).isEqualTo(DataConnectionState.Connected)
-        assertThat(conn.hasPrioritizedNetworkCapabilities.value).isFalse()
-        job.cancel()
+        kairos.transact {
+            assertThat(conn.subId).isEqualTo(model.subscriptionId)
+            assertThat(conn.cdmaLevel.sample()).isEqualTo(model.level)
+            assertThat(conn.primaryLevel.sample()).isEqualTo(model.level)
+            assertThat(conn.carrierNetworkChangeActive.sample()).isEqualTo(false)
+            assertThat(conn.isRoaming.sample()).isEqualTo(false)
+            assertThat(conn.isEmergencyOnly.sample()).isFalse()
+            assertThat(conn.isGsm.sample()).isFalse()
+            assertThat(conn.dataConnectionState.sample()).isEqualTo(DataConnectionState.Connected)
+            assertThat(conn.hasPrioritizedNetworkCapabilities.sample()).isFalse()
+        }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairosTest.kt
index 93d56d5..1838d13 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,281 +20,223 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.log.table.logcatTableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.fakeWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.wifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
-import com.android.systemui.util.mockito.whenever
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.stub
 
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CarrierMergedConnectionRepositoryKairosTest : SysuiTestCase() {
 
-    private lateinit var underTest: CarrierMergedConnectionRepositoryKairos
+    private val Kosmos.underTest by ActivatedKairosFixture {
+        CarrierMergedConnectionRepositoryKairos(
+            subId = SUB_ID,
+            tableLogBuffer = logcatTableLogBuffer(this),
+            telephonyManager = telephonyManager,
+            wifiRepository = wifiRepository,
+            isInEcmMode = stateOf(false),
+        )
+    }
 
-    private lateinit var wifiRepository: FakeWifiRepository
-    @Mock private lateinit var logger: TableLogBuffer
-    @Mock private lateinit var telephonyManager: TelephonyManager
+    private val Kosmos.telephonyManager: TelephonyManager by Fixture {
+        mock {
+            on { subscriptionId } doReturn SUB_ID
+            on { simOperatorName } doReturn ""
+        }
+    }
 
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        testKosmos().run {
+            useUnconfinedTestDispatcher()
+            runKairosTest { block() }
+        }
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        whenever(telephonyManager.subscriptionId).thenReturn(SUB_ID)
-        whenever(telephonyManager.simOperatorName).thenReturn("")
+    @Test
+    fun inactiveWifi_isDefault() = runTest {
+        val latestConnState by underTest.dataConnectionState.collectLastValue()
+        val latestNetType by underTest.resolvedNetworkType.collectLastValue()
 
-        wifiRepository = FakeWifiRepository()
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.Inactive())
 
-        underTest =
-            CarrierMergedConnectionRepositoryKairos(
-                SUB_ID,
-                logger,
-                telephonyManager,
-                testScope.backgroundScope.coroutineContext,
-                testScope.backgroundScope,
-                wifiRepository,
-            )
+        assertThat(latestConnState).isEqualTo(DataConnectionState.Disconnected)
+        assertThat(latestNetType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
     }
 
     @Test
-    fun inactiveWifi_isDefault() =
-        testScope.runTest {
-            var latestConnState: DataConnectionState? = null
-            var latestNetType: ResolvedNetworkType? = null
+    fun activeWifi_isDefault() = runTest {
+        val latestConnState by underTest.dataConnectionState.collectLastValue()
+        val latestNetType by underTest.resolvedNetworkType.collectLastValue()
 
-            val dataJob =
-                underTest.dataConnectionState.onEach { latestConnState = it }.launchIn(this)
-            val netJob = underTest.resolvedNetworkType.onEach { latestNetType = it }.launchIn(this)
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(level = 1))
 
-            wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive())
-
-            assertThat(latestConnState).isEqualTo(DataConnectionState.Disconnected)
-            assertThat(latestNetType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
-
-            dataJob.cancel()
-            netJob.cancel()
-        }
+        assertThat(latestConnState).isEqualTo(DataConnectionState.Disconnected)
+        assertThat(latestNetType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
+    }
 
     @Test
-    fun activeWifi_isDefault() =
-        testScope.runTest {
-            var latestConnState: DataConnectionState? = null
-            var latestNetType: ResolvedNetworkType? = null
+    fun carrierMergedWifi_isValidAndFieldsComeFromWifiNetwork() = runTest {
+        val latest by underTest.primaryLevel.collectLastValue()
 
-            val dataJob =
-                underTest.dataConnectionState.onEach { latestConnState = it }.launchIn(this)
-            val netJob = underTest.resolvedNetworkType.onEach { latestNetType = it }.launchIn(this)
+        fakeWifiRepository.setIsWifiEnabled(true)
+        fakeWifiRepository.setIsWifiDefault(true)
 
-            wifiRepository.setWifiNetwork(WifiNetworkModel.Active.of(level = 1))
+        fakeWifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
+        )
 
-            assertThat(latestConnState).isEqualTo(DataConnectionState.Disconnected)
-            assertThat(latestNetType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
-
-            dataJob.cancel()
-            netJob.cancel()
-        }
+        assertThat(latest).isEqualTo(3)
+    }
 
     @Test
-    fun carrierMergedWifi_isValidAndFieldsComeFromWifiNetwork() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.primaryLevel.onEach { latest = it }.launchIn(this)
+    fun activity_comesFromWifiActivity() = runTest {
+        val latest by underTest.dataActivityDirection.collectLastValue()
 
-            wifiRepository.setIsWifiEnabled(true)
-            wifiRepository.setIsWifiDefault(true)
+        fakeWifiRepository.setIsWifiEnabled(true)
+        fakeWifiRepository.setIsWifiDefault(true)
+        fakeWifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
+        )
+        fakeWifiRepository.setWifiActivity(
+            DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+        )
 
-            wifiRepository.setWifiNetwork(
-                WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
-            )
+        assertThat(latest!!.hasActivityIn).isTrue()
+        assertThat(latest!!.hasActivityOut).isFalse()
 
-            assertThat(latest).isEqualTo(3)
+        fakeWifiRepository.setWifiActivity(
+            DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+        )
 
-            job.cancel()
-        }
+        assertThat(latest!!.hasActivityIn).isFalse()
+        assertThat(latest!!.hasActivityOut).isTrue()
+    }
 
     @Test
-    fun activity_comesFromWifiActivity() =
-        testScope.runTest {
-            var latest: DataActivityModel? = null
-            val job = underTest.dataActivityDirection.onEach { latest = it }.launchIn(this)
+    fun carrierMergedWifi_wrongSubId_isDefault() = runTest {
+        val latestLevel by underTest.primaryLevel.collectLastValue()
+        val latestType by underTest.resolvedNetworkType.collectLastValue()
 
-            wifiRepository.setIsWifiEnabled(true)
-            wifiRepository.setIsWifiDefault(true)
-            wifiRepository.setWifiNetwork(
-                WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
-            )
-            wifiRepository.setWifiActivity(
-                DataActivityModel(hasActivityIn = true, hasActivityOut = false)
-            )
+        fakeWifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID + 10, level = 3)
+        )
 
-            assertThat(latest!!.hasActivityIn).isTrue()
-            assertThat(latest!!.hasActivityOut).isFalse()
-
-            wifiRepository.setWifiActivity(
-                DataActivityModel(hasActivityIn = false, hasActivityOut = true)
-            )
-
-            assertThat(latest!!.hasActivityIn).isFalse()
-            assertThat(latest!!.hasActivityOut).isTrue()
-
-            job.cancel()
-        }
-
-    @Test
-    fun carrierMergedWifi_wrongSubId_isDefault() =
-        testScope.runTest {
-            var latestLevel: Int? = null
-            var latestType: ResolvedNetworkType? = null
-            val levelJob = underTest.primaryLevel.onEach { latestLevel = it }.launchIn(this)
-            val typeJob = underTest.resolvedNetworkType.onEach { latestType = it }.launchIn(this)
-
-            wifiRepository.setWifiNetwork(
-                WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID + 10, level = 3)
-            )
-
-            assertThat(latestLevel).isNotEqualTo(3)
-            assertThat(latestType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
-
-            levelJob.cancel()
-            typeJob.cancel()
-        }
+        assertThat(latestLevel).isNotEqualTo(3)
+        assertThat(latestType).isNotEqualTo(ResolvedNetworkType.CarrierMergedNetworkType)
+    }
 
     // This scenario likely isn't possible, but write a test for it anyway
     @Test
-    fun carrierMergedButNotEnabled_isDefault() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.primaryLevel.onEach { latest = it }.launchIn(this)
+    fun carrierMergedButNotEnabled_isDefault() = runTest {
+        val latest by underTest.primaryLevel.collectLastValue()
 
-            wifiRepository.setWifiNetwork(
-                WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
-            )
-            wifiRepository.setIsWifiEnabled(false)
+        fakeWifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
+        )
+        fakeWifiRepository.setIsWifiEnabled(false)
 
-            assertThat(latest).isNotEqualTo(3)
-
-            job.cancel()
-        }
+        assertThat(latest).isNotEqualTo(3)
+    }
 
     // This scenario likely isn't possible, but write a test for it anyway
     @Test
-    fun carrierMergedButWifiNotDefault_isDefault() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.primaryLevel.onEach { latest = it }.launchIn(this)
+    fun carrierMergedButWifiNotDefault_isDefault() = runTest {
+        val latest by underTest.primaryLevel.collectLastValue()
 
-            wifiRepository.setWifiNetwork(
-                WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
+        fakeWifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
+        )
+        fakeWifiRepository.setIsWifiDefault(false)
+
+        assertThat(latest).isNotEqualTo(3)
+    }
+
+    @Test
+    fun numberOfLevels_comesFromCarrierMerged() = runTest {
+        val latest by underTest.numberOfLevels.collectLastValue()
+
+        fakeWifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged.of(
+                subscriptionId = SUB_ID,
+                level = 1,
+                numberOfLevels = 6,
             )
-            wifiRepository.setIsWifiDefault(false)
+        )
 
-            assertThat(latest).isNotEqualTo(3)
-
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(6)
+    }
 
     @Test
-    fun numberOfLevels_comesFromCarrierMerged() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
+    fun dataEnabled_matchesWifiEnabled() = runTest {
+        val latest by underTest.dataEnabled.collectLastValue()
 
-            wifiRepository.setWifiNetwork(
-                WifiNetworkModel.CarrierMerged.of(
-                    subscriptionId = SUB_ID,
-                    level = 1,
-                    numberOfLevels = 6,
-                )
-            )
+        fakeWifiRepository.setIsWifiEnabled(true)
+        assertThat(latest).isTrue()
 
-            assertThat(latest).isEqualTo(6)
-
-            job.cancel()
-        }
+        fakeWifiRepository.setIsWifiEnabled(false)
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun dataEnabled_matchesWifiEnabled() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
-
-            wifiRepository.setIsWifiEnabled(true)
-            assertThat(latest).isTrue()
-
-            wifiRepository.setIsWifiEnabled(false)
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
+    fun cdmaRoaming_alwaysFalse() = runTest {
+        val latest by underTest.cdmaRoaming.collectLastValue()
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun cdmaRoaming_alwaysFalse() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this)
+    fun networkName_usesSimOperatorNameAsInitial() = runTest {
+        telephonyManager.stub { on { simOperatorName } doReturn "Test SIM name" }
 
-            assertThat(latest).isFalse()
+        val latest by underTest.networkName.collectLastValue()
 
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
+    }
 
     @Test
-    fun networkName_usesSimOperatorNameAsInitial() =
-        testScope.runTest {
-            whenever(telephonyManager.simOperatorName).thenReturn("Test SIM name")
+    fun networkName_updatesOnNetworkUpdate() = runTest {
+        fakeWifiRepository.setIsWifiEnabled(true)
+        fakeWifiRepository.setIsWifiDefault(true)
 
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
+        telephonyManager.stub { on { simOperatorName } doReturn "Test SIM name" }
 
-            assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
+        val latest by underTest.networkName.collectLastValue()
 
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
+
+        telephonyManager.stub { on { simOperatorName } doReturn "New SIM name" }
+        fakeWifiRepository.setWifiNetwork(
+            WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
+        )
+
+        assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("New SIM name"))
+    }
 
     @Test
-    fun networkName_updatesOnNetworkUpdate() =
-        testScope.runTest {
-            whenever(telephonyManager.simOperatorName).thenReturn("Test SIM name")
+    fun isAllowedDuringAirplaneMode_alwaysTrue() = runTest {
+        val latest by underTest.isAllowedDuringAirplaneMode.collectLastValue()
 
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
-
-            whenever(telephonyManager.simOperatorName).thenReturn("New SIM name")
-            wifiRepository.setWifiNetwork(
-                WifiNetworkModel.CarrierMerged.of(subscriptionId = SUB_ID, level = 3)
-            )
-
-            assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("New SIM name"))
-
-            job.cancel()
-        }
-
-    @Test
-    fun isAllowedDuringAirplaneMode_alwaysTrue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode)
-
-            assertThat(latest).isTrue()
-        }
+        assertThat(latest).isTrue()
+    }
 
     private companion object {
         const val SUB_ID = 123
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairosTest.kt
index 56d76fc..858bb09 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
 
-import android.net.ConnectivityManager
 import android.os.PersistableBundle
 import android.telephony.ServiceState
 import android.telephony.SignalStrength
@@ -26,616 +25,512 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.FakeFeatureFlagsClassic
+import com.android.systemui.activated
 import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.BuildSpec
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.MutableState
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.log.table.logcatTableLogBuffer
-import com.android.systemui.log.table.tableLogBufferFactory
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_EMERGENCY
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_OPERATOR
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_PRIMARY_LEVEL
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_PRIMARY_LEVEL
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.getTelephonyCallbackForType
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.fakeWifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.wifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import java.io.PrintWriter
 import java.io.StringWriter
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
 
 /**
  * This repo acts as a dispatcher to either the `typical` or `carrier merged` versions of the
  * repository interface it's switching on. These tests just need to verify that the entire interface
  * properly switches over when the value of `isCarrierMerged` changes.
  */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FullMobileConnectionRepositoryKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
+    private val Kosmos.fakeMobileRepo by Fixture {
+        FakeMobileConnectionRepositoryKairos(SUB_ID, kairos, mobileLogger)
+    }
 
-    private lateinit var underTest: FullMobileConnectionRepositoryKairos
+    private val Kosmos.fakeCarrierMergedRepo by Fixture {
+        FakeMobileConnectionRepositoryKairos(SUB_ID, kairos, mobileLogger).apply {
+            // Mimicks the real carrier merged repository
+            isAllowedDuringAirplaneMode.setValue(true)
+        }
+    }
 
-    private val flags =
-        FakeFeatureFlagsClassic().also { it.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) }
+    private var Kosmos.mobileRepo: MobileConnectionRepositoryKairos by Fixture { fakeMobileRepo }
+    private var Kosmos.carrierMergedRepoSpec:
+        BuildSpec<MobileConnectionRepositoryKairos> by Fixture {
+        buildSpec { fakeCarrierMergedRepo }
+    }
 
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
-    private val tableLogBuffer = logcatTableLogBuffer(kosmos, "TestName")
-    private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>()
-    private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>()
-    private val connectivityManager = mock<ConnectivityManager>()
+    private val Kosmos.mobileLogger by Fixture { logcatTableLogBuffer(this, "TestName") }
 
-    private val subscriptionModel =
-        MutableStateFlow(
+    private val Kosmos.underTest by ActivatedKairosFixture {
+        FullMobileConnectionRepositoryKairos(
+            SUB_ID,
+            mobileLogger,
+            mobileRepo,
+            carrierMergedRepoSpec,
+            isCarrierMerged,
+        )
+    }
+
+    private val Kosmos.subscriptionModel by Fixture {
+        MutableState(
+            kairos,
             SubscriptionModel(
                 subscriptionId = SUB_ID,
                 carrierName = DEFAULT_NAME,
                 profileClass = PROFILE_CLASS_UNSET,
-            )
+            ),
         )
+    }
+
+    private val Kosmos.isCarrierMerged by Fixture { MutableState(kairos, false) }
 
     // Use a real config, with no overrides
     private val systemUiCarrierConfig = SystemUiCarrierConfig(SUB_ID, PersistableBundle())
 
-    private lateinit var mobileRepo: FakeMobileConnectionRepository
-    private lateinit var carrierMergedRepo: FakeMobileConnectionRepository
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            fakeFeatureFlagsClassic.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true)
+        }
 
-    @Before
-    fun setUp() {
-        mobileRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
-        carrierMergedRepo =
-            FakeMobileConnectionRepository(SUB_ID, tableLogBuffer).apply {
-                // Mimicks the real carrier merged repository
-                this.isAllowedDuringAirplaneMode.value = true
-            }
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
-        whenever(mobileFactory.build(eq(SUB_ID), any(), any(), eq(DEFAULT_NAME_MODEL), eq(SEP)))
-            .thenReturn(mobileRepo)
-        whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(carrierMergedRepo)
+    @Test
+    fun startingIsCarrierMerged_usesCarrierMergedInitially() = runTest {
+        val carrierMergedOperatorName = "Carrier Merged Operator"
+        val nonCarrierMergedName = "Non-carrier-merged"
+
+        fakeCarrierMergedRepo.operatorAlphaShort.setValue(carrierMergedOperatorName)
+        fakeMobileRepo.operatorAlphaShort.setValue(nonCarrierMergedName)
+
+        isCarrierMerged.setValue(true)
+
+        val activeRepo by underTest.activeRepo.collectLastValue()
+        val operatorAlphaShort by underTest.operatorAlphaShort.collectLastValue()
+
+        assertThat(activeRepo).isEqualTo(fakeCarrierMergedRepo)
+        assertThat(operatorAlphaShort).isEqualTo(carrierMergedOperatorName)
     }
 
     @Test
-    fun startingIsCarrierMerged_usesCarrierMergedInitially() =
-        testScope.runTest {
-            val carrierMergedOperatorName = "Carrier Merged Operator"
-            val nonCarrierMergedName = "Non-carrier-merged"
+    fun startingNotCarrierMerged_usesTypicalInitially() = runTest {
+        val carrierMergedOperatorName = "Carrier Merged Operator"
+        val nonCarrierMergedName = "Typical Operator"
 
-            carrierMergedRepo.operatorAlphaShort.value = carrierMergedOperatorName
-            mobileRepo.operatorAlphaShort.value = nonCarrierMergedName
+        fakeCarrierMergedRepo.operatorAlphaShort.setValue(carrierMergedOperatorName)
+        fakeMobileRepo.operatorAlphaShort.setValue(nonCarrierMergedName)
+        isCarrierMerged.setValue(false)
 
-            initializeRepo(startingIsCarrierMerged = true)
-
-            assertThat(underTest.activeRepo.value).isEqualTo(carrierMergedRepo)
-            assertThat(underTest.operatorAlphaShort.value).isEqualTo(carrierMergedOperatorName)
-            verify(mobileFactory, never())
-                .build(SUB_ID, tableLogBuffer, subscriptionModel, DEFAULT_NAME_MODEL, SEP)
-        }
-
-    @Test
-    fun startingNotCarrierMerged_usesTypicalInitially() =
-        testScope.runTest {
-            val carrierMergedOperatorName = "Carrier Merged Operator"
-            val nonCarrierMergedName = "Typical Operator"
-
-            carrierMergedRepo.operatorAlphaShort.value = carrierMergedOperatorName
-            mobileRepo.operatorAlphaShort.value = nonCarrierMergedName
-
-            initializeRepo(startingIsCarrierMerged = false)
-
-            assertThat(underTest.activeRepo.value).isEqualTo(mobileRepo)
-            assertThat(underTest.operatorAlphaShort.value).isEqualTo(nonCarrierMergedName)
-            verify(carrierMergedFactory, never()).build(SUB_ID, tableLogBuffer)
-        }
-
-    @Test
-    fun activeRepo_matchesIsCarrierMerged() =
-        testScope.runTest {
-            initializeRepo(startingIsCarrierMerged = false)
-            var latest: MobileConnectionRepository? = null
-            val job = underTest.activeRepo.onEach { latest = it }.launchIn(this)
-
-            underTest.setIsCarrierMerged(true)
-
-            assertThat(latest).isEqualTo(carrierMergedRepo)
-
-            underTest.setIsCarrierMerged(false)
-
-            assertThat(latest).isEqualTo(mobileRepo)
-
-            underTest.setIsCarrierMerged(true)
-
-            assertThat(latest).isEqualTo(carrierMergedRepo)
-
-            job.cancel()
-        }
-
-    @Test
-    fun connectionInfo_getsUpdatesFromRepo_carrierMerged() =
-        testScope.runTest {
-            initializeRepo(startingIsCarrierMerged = false)
-
-            var latestName: String? = null
-            var latestLevel: Int? = null
-
-            val nameJob = underTest.operatorAlphaShort.onEach { latestName = it }.launchIn(this)
-            val levelJob = underTest.primaryLevel.onEach { latestLevel = it }.launchIn(this)
-
-            underTest.setIsCarrierMerged(true)
-
-            val operator1 = "Carrier Merged Operator"
-            val level1 = 1
-            carrierMergedRepo.operatorAlphaShort.value = operator1
-            carrierMergedRepo.primaryLevel.value = level1
-
-            assertThat(latestName).isEqualTo(operator1)
-            assertThat(latestLevel).isEqualTo(level1)
-
-            val operator2 = "Carrier Merged Operator #2"
-            val level2 = 2
-            carrierMergedRepo.operatorAlphaShort.value = operator2
-            carrierMergedRepo.primaryLevel.value = level2
-
-            assertThat(latestName).isEqualTo(operator2)
-            assertThat(latestLevel).isEqualTo(level2)
-
-            val operator3 = "Carrier Merged Operator #3"
-            val level3 = 3
-            carrierMergedRepo.operatorAlphaShort.value = operator3
-            carrierMergedRepo.primaryLevel.value = level3
-
-            assertThat(latestName).isEqualTo(operator3)
-            assertThat(latestLevel).isEqualTo(level3)
-
-            nameJob.cancel()
-            levelJob.cancel()
-        }
-
-    @Test
-    fun connectionInfo_getsUpdatesFromRepo_mobile() =
-        testScope.runTest {
-            initializeRepo(startingIsCarrierMerged = false)
-
-            var latestName: String? = null
-            var latestLevel: Int? = null
-
-            val nameJob = underTest.operatorAlphaShort.onEach { latestName = it }.launchIn(this)
-            val levelJob = underTest.primaryLevel.onEach { latestLevel = it }.launchIn(this)
-
-            underTest.setIsCarrierMerged(false)
-
-            val operator1 = "Typical Merged Operator"
-            val level1 = 1
-            mobileRepo.operatorAlphaShort.value = operator1
-            mobileRepo.primaryLevel.value = level1
-
-            assertThat(latestName).isEqualTo(operator1)
-            assertThat(latestLevel).isEqualTo(level1)
-
-            val operator2 = "Typical Merged Operator #2"
-            val level2 = 2
-            mobileRepo.operatorAlphaShort.value = operator2
-            mobileRepo.primaryLevel.value = level2
-
-            assertThat(latestName).isEqualTo(operator2)
-            assertThat(latestLevel).isEqualTo(level2)
-
-            val operator3 = "Typical Merged Operator #3"
-            val level3 = 3
-            mobileRepo.operatorAlphaShort.value = operator3
-            mobileRepo.primaryLevel.value = level3
-
-            assertThat(latestName).isEqualTo(operator3)
-            assertThat(latestLevel).isEqualTo(level3)
-
-            nameJob.cancel()
-            levelJob.cancel()
-        }
-
-    @Test
-    fun connectionInfo_updatesWhenCarrierMergedUpdates() =
-        testScope.runTest {
-            initializeRepo(startingIsCarrierMerged = false)
-
-            var latestName: String? = null
-            var latestLevel: Int? = null
-
-            val nameJob = underTest.operatorAlphaShort.onEach { latestName = it }.launchIn(this)
-            val levelJob = underTest.primaryLevel.onEach { latestLevel = it }.launchIn(this)
-
-            val carrierMergedOperator = "Carrier Merged Operator"
-            val carrierMergedLevel = 4
-            carrierMergedRepo.operatorAlphaShort.value = carrierMergedOperator
-            carrierMergedRepo.primaryLevel.value = carrierMergedLevel
-
-            val mobileName = "Typical Operator"
-            val mobileLevel = 2
-            mobileRepo.operatorAlphaShort.value = mobileName
-            mobileRepo.primaryLevel.value = mobileLevel
-
-            // Start with the mobile info
-            assertThat(latestName).isEqualTo(mobileName)
-            assertThat(latestLevel).isEqualTo(mobileLevel)
-
-            // WHEN isCarrierMerged is set to true
-            underTest.setIsCarrierMerged(true)
-
-            // THEN the carrier merged info is used
-            assertThat(latestName).isEqualTo(carrierMergedOperator)
-            assertThat(latestLevel).isEqualTo(carrierMergedLevel)
-
-            val newCarrierMergedName = "New CM Operator"
-            val newCarrierMergedLevel = 0
-            carrierMergedRepo.operatorAlphaShort.value = newCarrierMergedName
-            carrierMergedRepo.primaryLevel.value = newCarrierMergedLevel
-
-            assertThat(latestName).isEqualTo(newCarrierMergedName)
-            assertThat(latestLevel).isEqualTo(newCarrierMergedLevel)
-
-            // WHEN isCarrierMerged is set to false
-            underTest.setIsCarrierMerged(false)
-
-            // THEN the typical info is used
-            assertThat(latestName).isEqualTo(mobileName)
-            assertThat(latestLevel).isEqualTo(mobileLevel)
-
-            val newMobileName = "New MobileOperator"
-            val newMobileLevel = 3
-            mobileRepo.operatorAlphaShort.value = newMobileName
-            mobileRepo.primaryLevel.value = newMobileLevel
-
-            assertThat(latestName).isEqualTo(newMobileName)
-            assertThat(latestLevel).isEqualTo(newMobileLevel)
-
-            nameJob.cancel()
-            levelJob.cancel()
-        }
-
-    @Test
-    fun isAllowedDuringAirplaneMode_updatesWhenCarrierMergedUpdates() =
-        testScope.runTest {
-            initializeRepo(startingIsCarrierMerged = false)
-
-            val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode)
-
-            assertThat(latest).isFalse()
-
-            underTest.setIsCarrierMerged(true)
-
-            assertThat(latest).isTrue()
-
-            underTest.setIsCarrierMerged(false)
-
-            assertThat(latest).isFalse()
-        }
-
-    @Test
-    fun factory_reusesLogBuffersForSameConnection() =
-        testScope.runTest {
-            val factory =
-                FullMobileConnectionRepository.Factory(
-                    scope = testScope.backgroundScope,
-                    kosmos.tableLogBufferFactory,
-                    mobileFactory,
-                    carrierMergedFactory,
-                )
-
-            // Create two connections for the same subId. Similar to if the connection appeared
-            // and disappeared from the connectionFactory's perspective
-            val connection1 =
-                factory.build(
-                    SUB_ID,
-                    startingIsCarrierMerged = false,
-                    subscriptionModel,
-                    DEFAULT_NAME_MODEL,
-                    SEP,
-                )
-
-            val connection1Repeat =
-                factory.build(
-                    SUB_ID,
-                    startingIsCarrierMerged = false,
-                    subscriptionModel,
-                    DEFAULT_NAME_MODEL,
-                    SEP,
-                )
-
-            assertThat(connection1.tableLogBuffer)
-                .isSameInstanceAs(connection1Repeat.tableLogBuffer)
-        }
-
-    @Test
-    fun factory_reusesLogBuffersForSameSubIDevenIfCarrierMerged() =
-        testScope.runTest {
-            val factory =
-                FullMobileConnectionRepository.Factory(
-                    scope = testScope.backgroundScope,
-                    kosmos.tableLogBufferFactory,
-                    mobileFactory,
-                    carrierMergedFactory,
-                )
-
-            val connection1 =
-                factory.build(
-                    SUB_ID,
-                    startingIsCarrierMerged = false,
-                    subscriptionModel,
-                    DEFAULT_NAME_MODEL,
-                    SEP,
-                )
-
-            // WHEN a connection with the same sub ID but carrierMerged = true is created
-            val connection1Repeat =
-                factory.build(
-                    SUB_ID,
-                    startingIsCarrierMerged = true,
-                    subscriptionModel,
-                    DEFAULT_NAME_MODEL,
-                    SEP,
-                )
-
-            // THEN the same table is re-used
-            assertThat(connection1.tableLogBuffer)
-                .isSameInstanceAs(connection1Repeat.tableLogBuffer)
-        }
-
-    @Test
-    fun connectionInfo_logging_notCarrierMerged_getsUpdates() =
-        testScope.runTest {
-            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
-            val telephonyManager =
-                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
-            createRealMobileRepo(telephonyManager)
-            createRealCarrierMergedRepo(telephonyManager, FakeWifiRepository())
-
-            initializeRepo(startingIsCarrierMerged = false)
-
-            val emergencyJob = underTest.isEmergencyOnly.launchIn(this)
-            val operatorJob = underTest.operatorAlphaShort.launchIn(this)
-
-            // WHEN we set up some mobile connection info
-            val serviceState = ServiceState()
-            serviceState.setOperatorName("longName", "OpTypical", "1")
-            serviceState.isEmergencyOnly = true
-            getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager)
-                .onServiceStateChanged(serviceState)
-
-            // THEN it's logged to the buffer
-            assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpTypical")
-            assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}true")
-
-            // WHEN we update mobile connection info
-            val serviceState2 = ServiceState()
-            serviceState2.setOperatorName("longName", "OpDiff", "1")
-            serviceState2.isEmergencyOnly = false
-            getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager)
-                .onServiceStateChanged(serviceState2)
-
-            // THEN the updates are logged
-            assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpDiff")
-            assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}false")
-
-            emergencyJob.cancel()
-            operatorJob.cancel()
-        }
-
-    @Test
-    fun connectionInfo_logging_carrierMerged_getsUpdates() =
-        testScope.runTest {
-            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
-            val telephonyManager =
-                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
-            createRealMobileRepo(telephonyManager)
-            val wifiRepository = FakeWifiRepository()
-            createRealCarrierMergedRepo(telephonyManager, wifiRepository)
-
-            initializeRepo(startingIsCarrierMerged = true)
-
-            val job = underTest.primaryLevel.launchIn(this)
-
-            // WHEN we set up carrier merged info
-            wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 3))
-
-            // THEN the carrier merged info is logged
-            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
-
-            // WHEN we update the info
-            wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 1))
-
-            // THEN the updates are logged
-            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
-
-            job.cancel()
-        }
-
-    @Test
-    fun connectionInfo_logging_updatesWhenCarrierMergedUpdates() =
-        testScope.runTest {
-            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
-            val telephonyManager =
-                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
-            createRealMobileRepo(telephonyManager)
-
-            val wifiRepository = FakeWifiRepository()
-            createRealCarrierMergedRepo(telephonyManager, wifiRepository)
-
-            initializeRepo(startingIsCarrierMerged = false)
-
-            val job = underTest.primaryLevel.launchIn(this)
-
-            // WHEN we set up some mobile connection info
-            val signalStrength = mock<SignalStrength>()
-            whenever(signalStrength.level).thenReturn(1)
-
-            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
-                .onSignalStrengthsChanged(signalStrength)
-
-            // THEN it's logged to the buffer
-            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
-
-            // WHEN isCarrierMerged is set to true
-            wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 3))
-            underTest.setIsCarrierMerged(true)
-
-            // THEN the carrier merged info is logged
-            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
-
-            // WHEN the carrier merge network is updated
-            wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 4))
-
-            // THEN the new level is logged
-            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4")
-
-            // WHEN isCarrierMerged is set to false
-            underTest.setIsCarrierMerged(false)
-
-            // THEN the typical info is logged
-            // Note: Since our first logs also had the typical info, we need to search the log
-            // contents for after our carrier merged level log.
-            val fullBuffer = dumpBuffer()
-            val carrierMergedContentIndex = fullBuffer.indexOf("${BUFFER_SEPARATOR}4")
-            val bufferAfterCarrierMerged = fullBuffer.substring(carrierMergedContentIndex)
-            assertThat(bufferAfterCarrierMerged).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
-
-            // WHEN the normal network is updated
-            mobileRepo.primaryLevel.value = 0
-
-            // THEN the new level is logged
-            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}0")
-
-            job.cancel()
-        }
-
-    @Test
-    fun connectionInfo_logging_doesNotLogUpdatesForNotActiveRepo() =
-        testScope.runTest {
-            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
-            val telephonyManager =
-                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
-            createRealMobileRepo(telephonyManager)
-
-            val wifiRepository = FakeWifiRepository()
-            createRealCarrierMergedRepo(telephonyManager, wifiRepository)
-
-            // WHEN isCarrierMerged = false
-            initializeRepo(startingIsCarrierMerged = false)
-
-            val job = underTest.primaryLevel.launchIn(this)
-
-            val signalStrength = mock<SignalStrength>()
-            whenever(signalStrength.level).thenReturn(1)
-            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
-                .onSignalStrengthsChanged(signalStrength)
-
-            // THEN updates to the carrier merged level aren't logged
-            wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 4))
-            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4")
-
-            wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 3))
-            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
-
-            // WHEN isCarrierMerged is set to true
-            underTest.setIsCarrierMerged(true)
-
-            // THEN updates to the normal level aren't logged
-            whenever(signalStrength.level).thenReturn(5)
-            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
-                .onSignalStrengthsChanged(signalStrength)
-            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}5")
-
-            whenever(signalStrength.level).thenReturn(6)
-            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
-                .onSignalStrengthsChanged(signalStrength)
-            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}6")
-
-            job.cancel()
-        }
-
-    private fun initializeRepo(startingIsCarrierMerged: Boolean) {
-        underTest =
-            FullMobileConnectionRepositoryKairos(
-                SUB_ID,
-                startingIsCarrierMerged,
-                tableLogBuffer,
-                subscriptionModel,
-                DEFAULT_NAME_MODEL,
-                SEP,
-                testScope.backgroundScope,
-                mobileFactory,
-                carrierMergedFactory,
-            )
+        assertThat(underTest.activeRepo.collectLastValue().value).isEqualTo(fakeMobileRepo)
+        assertThat(underTest.operatorAlphaShort.collectLastValue().value)
+            .isEqualTo(nonCarrierMergedName)
     }
 
-    private fun createRealMobileRepo(
+    @Test
+    fun activeRepo_matchesIsCarrierMerged() = runTest {
+        isCarrierMerged.setValue(false)
+
+        val latest by underTest.activeRepo.collectLastValue()
+
+        isCarrierMerged.setValue(true)
+
+        assertThat(latest).isEqualTo(fakeCarrierMergedRepo)
+
+        isCarrierMerged.setValue(false)
+
+        assertThat(latest).isEqualTo(fakeMobileRepo)
+
+        isCarrierMerged.setValue(true)
+
+        assertThat(latest).isEqualTo(fakeCarrierMergedRepo)
+    }
+
+    @Test
+    fun connectionInfo_getsUpdatesFromRepo_carrierMerged() = runTest {
+        isCarrierMerged.setValue(false)
+
+        val latestName by underTest.operatorAlphaShort.collectLastValue()
+        val latestLevel by underTest.primaryLevel.collectLastValue()
+
+        isCarrierMerged.setValue(true)
+
+        val operator1 = "Carrier Merged Operator"
+        val level1 = 1
+        fakeCarrierMergedRepo.operatorAlphaShort.setValue(operator1)
+        fakeCarrierMergedRepo.primaryLevel.setValue(level1)
+
+        assertThat(latestName).isEqualTo(operator1)
+        assertThat(latestLevel).isEqualTo(level1)
+
+        val operator2 = "Carrier Merged Operator #2"
+        val level2 = 2
+        fakeCarrierMergedRepo.operatorAlphaShort.setValue(operator2)
+        fakeCarrierMergedRepo.primaryLevel.setValue(level2)
+
+        assertThat(latestName).isEqualTo(operator2)
+        assertThat(latestLevel).isEqualTo(level2)
+
+        val operator3 = "Carrier Merged Operator #3"
+        val level3 = 3
+        fakeCarrierMergedRepo.operatorAlphaShort.setValue(operator3)
+        fakeCarrierMergedRepo.primaryLevel.setValue(level3)
+
+        assertThat(latestName).isEqualTo(operator3)
+        assertThat(latestLevel).isEqualTo(level3)
+    }
+
+    @Test
+    fun connectionInfo_getsUpdatesFromRepo_mobile() = runTest {
+        isCarrierMerged.setValue(false)
+
+        val latestName by underTest.operatorAlphaShort.collectLastValue()
+        val latestLevel by underTest.primaryLevel.collectLastValue()
+
+        isCarrierMerged.setValue(false)
+
+        val operator1 = "Typical Merged Operator"
+        val level1 = 1
+        fakeMobileRepo.operatorAlphaShort.setValue(operator1)
+        fakeMobileRepo.primaryLevel.setValue(level1)
+
+        assertThat(latestName).isEqualTo(operator1)
+        assertThat(latestLevel).isEqualTo(level1)
+
+        val operator2 = "Typical Merged Operator #2"
+        val level2 = 2
+        fakeMobileRepo.operatorAlphaShort.setValue(operator2)
+        fakeMobileRepo.primaryLevel.setValue(level2)
+
+        assertThat(latestName).isEqualTo(operator2)
+        assertThat(latestLevel).isEqualTo(level2)
+
+        val operator3 = "Typical Merged Operator #3"
+        val level3 = 3
+        fakeMobileRepo.operatorAlphaShort.setValue(operator3)
+        fakeMobileRepo.primaryLevel.setValue(level3)
+
+        assertThat(latestName).isEqualTo(operator3)
+        assertThat(latestLevel).isEqualTo(level3)
+    }
+
+    @Test
+    fun connectionInfo_updatesWhenCarrierMergedUpdates() = runTest {
+        isCarrierMerged.setValue(false)
+
+        val latestName by underTest.operatorAlphaShort.collectLastValue()
+        val latestLevel by underTest.primaryLevel.collectLastValue()
+
+        val carrierMergedOperator = "Carrier Merged Operator"
+        val carrierMergedLevel = 4
+        fakeCarrierMergedRepo.operatorAlphaShort.setValue(carrierMergedOperator)
+        fakeCarrierMergedRepo.primaryLevel.setValue(carrierMergedLevel)
+
+        val mobileName = "Typical Operator"
+        val mobileLevel = 2
+        fakeMobileRepo.operatorAlphaShort.setValue(mobileName)
+        fakeMobileRepo.primaryLevel.setValue(mobileLevel)
+
+        // Start with the mobile info
+        assertThat(latestName).isEqualTo(mobileName)
+        assertThat(latestLevel).isEqualTo(mobileLevel)
+
+        // WHEN isCarrierMerged is set to true
+        isCarrierMerged.setValue(true)
+
+        // THEN the carrier merged info is used
+        assertThat(latestName).isEqualTo(carrierMergedOperator)
+        assertThat(latestLevel).isEqualTo(carrierMergedLevel)
+
+        val newCarrierMergedName = "New CM Operator"
+        val newCarrierMergedLevel = 0
+        fakeCarrierMergedRepo.operatorAlphaShort.setValue(newCarrierMergedName)
+        fakeCarrierMergedRepo.primaryLevel.setValue(newCarrierMergedLevel)
+
+        assertThat(latestName).isEqualTo(newCarrierMergedName)
+        assertThat(latestLevel).isEqualTo(newCarrierMergedLevel)
+
+        // WHEN isCarrierMerged is set to false
+        isCarrierMerged.setValue(false)
+
+        // THEN the typical info is used
+        assertThat(latestName).isEqualTo(mobileName)
+        assertThat(latestLevel).isEqualTo(mobileLevel)
+
+        val newMobileName = "New MobileOperator"
+        val newMobileLevel = 3
+        fakeMobileRepo.operatorAlphaShort.setValue(newMobileName)
+        fakeMobileRepo.primaryLevel.setValue(newMobileLevel)
+
+        assertThat(latestName).isEqualTo(newMobileName)
+        assertThat(latestLevel).isEqualTo(newMobileLevel)
+    }
+
+    @Test
+    fun isAllowedDuringAirplaneMode_updatesWhenCarrierMergedUpdates() = runTest {
+        isCarrierMerged.setValue(false)
+
+        val latest by underTest.isAllowedDuringAirplaneMode.collectLastValue()
+
+        assertThat(latest).isFalse()
+
+        isCarrierMerged.setValue(true)
+
+        assertThat(latest).isTrue()
+
+        isCarrierMerged.setValue(false)
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun connectionInfo_logging_notCarrierMerged_getsUpdates() = runTest {
+        // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+        val telephonyManager: TelephonyManager = mock {
+            on { simOperatorName } doReturn ""
+            on { subscriptionId } doReturn SUB_ID
+        }
+        fakeWifiRepository.setIsWifiEnabled(true)
+        fakeWifiRepository.setIsWifiDefault(true)
+        mobileRepo = createRealMobileRepo(telephonyManager)
+        carrierMergedRepoSpec = realCarrierMergedRepo(telephonyManager)
+
+        isCarrierMerged.setValue(false)
+
+        // Stand-up activated repository
+        underTest
+
+        // WHEN we set up some mobile connection info
+        val serviceState = ServiceState()
+        serviceState.setOperatorName("longName", "OpTypical", "1")
+        serviceState.isEmergencyOnly = true
+        getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager)
+            .onServiceStateChanged(serviceState)
+
+        // THEN it's logged to the buffer
+        assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpTypical")
+        assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}true")
+
+        // WHEN we update mobile connection info
+        val serviceState2 = ServiceState()
+        serviceState2.setOperatorName("longName", "OpDiff", "1")
+        serviceState2.isEmergencyOnly = false
+        getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager)
+            .onServiceStateChanged(serviceState2)
+
+        // THEN the updates are logged
+        assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpDiff")
+        assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}false")
+    }
+
+    @Test
+    fun connectionInfo_logging_carrierMerged_getsUpdates() = runTest {
+        // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+        val telephonyManager: TelephonyManager = mock {
+            on { simOperatorName } doReturn ""
+            on { subscriptionId } doReturn SUB_ID
+        }
+        fakeWifiRepository.setIsWifiEnabled(true)
+        fakeWifiRepository.setIsWifiDefault(true)
+        mobileRepo = createRealMobileRepo(telephonyManager)
+        carrierMergedRepoSpec = realCarrierMergedRepo(telephonyManager)
+
+        isCarrierMerged.setValue(true)
+
+        // Stand-up activated repository
+        underTest
+
+        // WHEN we set up carrier merged info
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 3))
+
+        // THEN the carrier merged info is logged
+        assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
+
+        // WHEN we update the info
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 1))
+
+        // THEN the updates are logged
+        assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
+    }
+
+    @Test
+    fun connectionInfo_logging_updatesWhenCarrierMergedUpdates() = runTest {
+        // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+        val telephonyManager: TelephonyManager = mock {
+            on { simOperatorName } doReturn ""
+            on { subscriptionId } doReturn SUB_ID
+        }
+        fakeWifiRepository.setIsWifiEnabled(true)
+        fakeWifiRepository.setIsWifiDefault(true)
+        mobileRepo = createRealMobileRepo(telephonyManager)
+        carrierMergedRepoSpec = realCarrierMergedRepo(telephonyManager)
+
+        isCarrierMerged.setValue(false)
+
+        // Stand-up activated repository
+        underTest
+
+        // WHEN we set up some mobile connection info
+        val cb =
+            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
+        cb.onSignalStrengthsChanged(mock(stubOnly = true) { on { level } doReturn 1 })
+
+        // THEN it's logged to the buffer
+        assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
+
+        // WHEN isCarrierMerged is set to true
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 3))
+        isCarrierMerged.setValue(true)
+
+        // THEN the carrier merged info is logged
+        assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
+
+        // WHEN the carrier merge network is updated
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 4))
+
+        // THEN the new level is logged
+        assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4")
+
+        // WHEN isCarrierMerged is set to false
+        isCarrierMerged.setValue(false)
+
+        // THEN the typical info is logged
+        // Note: Since our first logs also had the typical info, we need to search the log
+        // contents for after our carrier merged level log.
+        val fullBuffer = dumpBuffer()
+        val carrierMergedContentIndex = fullBuffer.indexOf("${BUFFER_SEPARATOR}4")
+        val bufferAfterCarrierMerged = fullBuffer.substring(carrierMergedContentIndex)
+        assertThat(bufferAfterCarrierMerged).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
+
+        // WHEN the normal network is updated
+        cb.onSignalStrengthsChanged(mock(stubOnly = true) { on { level } doReturn 0 })
+
+        // THEN the new level is logged
+        assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}0")
+    }
+
+    @Test
+    fun connectionInfo_logging_doesNotLogUpdatesForNotActiveRepo() = runTest {
+        // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+        val telephonyManager: TelephonyManager = mock {
+            on { simOperatorName } doReturn ""
+            on { subscriptionId } doReturn SUB_ID
+        }
+        fakeWifiRepository.setIsWifiEnabled(true)
+        fakeWifiRepository.setIsWifiDefault(true)
+        mobileRepo = createRealMobileRepo(telephonyManager)
+        carrierMergedRepoSpec = realCarrierMergedRepo(telephonyManager)
+
+        // WHEN isCarrierMerged = false
+        isCarrierMerged.setValue(false)
+
+        // Stand-up activated repository
+        underTest
+
+        fun setSignalLevel(newLevel: Int) {
+            val signalStrength =
+                mock<SignalStrength>(stubOnly = true) { on { level } doReturn newLevel }
+            argumentCaptor<TelephonyCallback>()
+                .apply { verify(telephonyManager).registerTelephonyCallback(any(), capture()) }
+                .allValues
+                .asSequence()
+                .filterIsInstance<TelephonyCallback.SignalStrengthsListener>()
+                .forEach { it.onSignalStrengthsChanged(signalStrength) }
+        }
+
+        // WHEN we set up some mobile connection info
+        setSignalLevel(1)
+
+        // THEN updates to the carrier merged level aren't logged
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 4))
+        assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4")
+
+        fakeWifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged.of(SUB_ID, level = 3))
+        assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
+
+        // WHEN isCarrierMerged is set to true
+        isCarrierMerged.setValue(true)
+
+        // THEN updates to the normal level aren't logged
+        setSignalLevel(5)
+        assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}5")
+
+        setSignalLevel(6)
+        assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}6")
+    }
+
+    private fun KairosTestScope.createRealMobileRepo(
         telephonyManager: TelephonyManager
-    ): MobileConnectionRepositoryImpl {
-        whenever(telephonyManager.subscriptionId).thenReturn(SUB_ID)
-        val realRepo =
-            MobileConnectionRepositoryImpl(
-                SUB_ID,
-                context,
-                subscriptionModel,
-                DEFAULT_NAME_MODEL,
-                SEP,
-                connectivityManager,
-                telephonyManager,
+    ): MobileConnectionRepositoryKairosImpl =
+        MobileConnectionRepositoryKairosImpl(
+                subId = SUB_ID,
+                context = context,
+                subscriptionModel = subscriptionModel,
+                defaultNetworkName = DEFAULT_NAME_MODEL,
+                networkNameSeparator = SEP,
+                connectivityManager = mock(stubOnly = true),
+                telephonyManager = telephonyManager,
                 systemUiCarrierConfig = systemUiCarrierConfig,
-                fakeBroadcastDispatcher,
-                mobileMappingsProxy = mock(),
-                testDispatcher,
-                logger = mock(),
-                tableLogBuffer,
-                flags,
-                testScope.backgroundScope,
+                broadcastDispatcher = fakeBroadcastDispatcher,
+                mobileMappingsProxy = mock(stubOnly = true),
+                bgDispatcher = testDispatcher,
+                logger = mock(stubOnly = true),
+                tableLogBuffer = mobileLogger,
+                flags = featureFlagsClassic,
             )
-        whenever(mobileFactory.build(eq(SUB_ID), any(), any(), eq(DEFAULT_NAME_MODEL), eq(SEP)))
-            .thenReturn(realRepo)
+            .activated()
 
-        return realRepo
+    private fun Kosmos.realCarrierMergedRepo(
+        telephonyManager: TelephonyManager
+    ): BuildSpec<CarrierMergedConnectionRepositoryKairos> = buildSpec {
+        activated {
+            CarrierMergedConnectionRepositoryKairos(
+                subId = SUB_ID,
+                tableLogBuffer = mobileLogger,
+                telephonyManager = telephonyManager,
+                wifiRepository = wifiRepository,
+                isInEcmMode = stateOf(false),
+            )
+        }
     }
 
-    private fun createRealCarrierMergedRepo(
-        telephonyManager: TelephonyManager,
-        wifiRepository: FakeWifiRepository,
-    ): CarrierMergedConnectionRepository {
-        wifiRepository.setIsWifiEnabled(true)
-        wifiRepository.setIsWifiDefault(true)
-        val realRepo =
-            CarrierMergedConnectionRepository(
-                SUB_ID,
-                tableLogBuffer,
-                telephonyManager,
-                testScope.backgroundScope.coroutineContext,
-                testScope.backgroundScope,
-                wifiRepository,
-            )
-        whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(realRepo)
-
-        return realRepo
-    }
-
-    private fun dumpBuffer(): String {
+    private fun Kosmos.dumpBuffer(): String {
         val outputWriter = StringWriter()
-        tableLogBuffer.dump(PrintWriter(outputWriter), arrayOf())
+        mobileLogger.dump(PrintWriter(outputWriter), arrayOf())
         return outputWriter.toString()
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosTest.kt
index 3a335b7..32fc359 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@
 import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.Intent
-import android.net.ConnectivityManager
 import android.net.ConnectivityManager.NetworkCallback
+import android.net.connectivityManager
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WLAN
@@ -68,19 +68,32 @@
 import android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID
 import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
 import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
+import android.telephony.telephonyManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.mobile.MobileMappings
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.MutableState
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogcatEchoTrackerAlways
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.tableLogBufferFactory
 import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
-import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
@@ -89,53 +102,495 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.testCarrierConfig
 import com.android.systemui.statusbar.pipeline.mobile.data.model.testCarrierConfigWithOverride
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.signalStrength
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.telephonyDisplayInfo
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.whenever
 
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileConnectionRepositoryKairosTest : SysuiTestCase() {
-    private lateinit var underTest: MobileConnectionRepositoryKairosImpl
 
-    private val flags =
-        FakeFeatureFlagsClassic().also { it.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) }
+    private val Kosmos.underTest by ActivatedKairosFixture {
+        MobileConnectionRepositoryKairosImpl(
+            SUB_1_ID,
+            context,
+            subscriptionModel,
+            DEFAULT_NAME_MODEL,
+            SEP,
+            connectivityManager,
+            telephonyManager,
+            systemUiCarrierConfig,
+            fakeBroadcastDispatcher,
+            mobileMappingsProxy,
+            testDispatcher,
+            logger,
+            tableLogger,
+            featureFlagsClassic,
+        )
+    }
 
-    @Mock private lateinit var connectivityManager: ConnectivityManager
-    @Mock private lateinit var telephonyManager: TelephonyManager
-    @Mock private lateinit var logger: MobileInputLogger
-    @Mock private lateinit var tableLogger: TableLogBuffer
-    @Mock private lateinit var context: Context
+    private val Kosmos.logger: MobileInputLogger by Fixture {
+        MobileInputLogger(LogBuffer("test_buffer", 1, LogcatEchoTrackerAlways()))
+    }
 
-    private val mobileMappings = FakeMobileMappingsProxy()
+    private val Kosmos.tableLogger: TableLogBuffer by Fixture {
+        tableLogBufferFactory.getOrCreate("test_buffer", 1)
+    }
+
+    private val Kosmos.context: Context by Fixture { mock() }
+
     private val systemUiCarrierConfig = SystemUiCarrierConfig(SUB_1_ID, testCarrierConfig())
 
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private val Kosmos.subscriptionModel: MutableState<SubscriptionModel?> by Fixture {
+        MutableState(
+            kairos,
+            SubscriptionModel(
+                subscriptionId = SUB_1_ID,
+                carrierName = DEFAULT_NAME,
+                profileClass = PROFILE_CLASS_UNSET,
+            ),
+        )
+    }
 
-    private val subscriptionModel: MutableStateFlow<SubscriptionModel?> =
-        MutableStateFlow(
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            featureFlagsClassic.fake.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true)
+            telephonyManager.stub { on { subscriptionId } doReturn SUB_1_ID }
+        }
+
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
+
+    @Test
+    fun emergencyOnly() = runTest {
+        val latest by underTest.isEmergencyOnly.collectLastValue()
+
+        val serviceState = ServiceState().apply { isEmergencyOnly = true }
+
+        getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
+
+        assertThat(latest).isEqualTo(true)
+    }
+
+    @Test
+    fun emergencyOnly_toggles() = runTest {
+        val latest by underTest.isEmergencyOnly.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<ServiceStateListener>()
+        callback.onServiceStateChanged(ServiceState().apply { isEmergencyOnly = true })
+
+        assertThat(latest).isTrue()
+
+        callback.onServiceStateChanged(ServiceState().apply { isEmergencyOnly = false })
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun cdmaLevelUpdates() = runTest {
+        val latest by underTest.cdmaLevel.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>()
+        var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true)
+        callback.onSignalStrengthsChanged(strength)
+
+        assertThat(latest).isEqualTo(2)
+
+        // gsmLevel updates, no change to cdmaLevel
+        strength = signalStrength(gsmLevel = 3, cdmaLevel = 2, isGsm = true)
+        callback.onSignalStrengthsChanged(strength)
+
+        assertThat(latest).isEqualTo(2)
+    }
+
+    @Test
+    fun gsmLevelUpdates() = runTest {
+        val latest by underTest.primaryLevel.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>()
+        var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true)
+        callback.onSignalStrengthsChanged(strength)
+
+        assertThat(latest).isEqualTo(1)
+
+        strength = signalStrength(gsmLevel = 3, cdmaLevel = 2, isGsm = true)
+        callback.onSignalStrengthsChanged(strength)
+
+        assertThat(latest).isEqualTo(3)
+    }
+
+    @Test
+    fun isGsm() = runTest {
+        val latest by underTest.isGsm.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>()
+        var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true)
+        callback.onSignalStrengthsChanged(strength)
+
+        assertThat(latest).isTrue()
+
+        strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = false)
+        callback.onSignalStrengthsChanged(strength)
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun dataConnectionState_connected() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(DATA_CONNECTED, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.Connected)
+    }
+
+    @Test
+    fun dataConnectionState_connecting() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(DATA_CONNECTING, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.Connecting)
+    }
+
+    @Test
+    fun dataConnectionState_disconnected() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(DATA_DISCONNECTED, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.Disconnected)
+    }
+
+    @Test
+    fun dataConnectionState_disconnecting() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(DATA_DISCONNECTING, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.Disconnecting)
+    }
+
+    @Test
+    fun dataConnectionState_suspended() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(DATA_SUSPENDED, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.Suspended)
+    }
+
+    @Test
+    fun dataConnectionState_handoverInProgress() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(DATA_HANDOVER_IN_PROGRESS, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.HandoverInProgress)
+    }
+
+    @Test
+    fun dataConnectionState_unknown() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(DATA_UNKNOWN, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.Unknown)
+    }
+
+    @Test
+    fun dataConnectionState_invalid() = runTest {
+        val latest by underTest.dataConnectionState.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+        callback.onDataConnectionStateChanged(45, 200 /* unused */)
+
+        assertThat(latest).isEqualTo(DataConnectionState.Invalid)
+    }
+
+    @Test
+    fun dataActivity() = runTest {
+        val latest by underTest.dataActivityDirection.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<DataActivityListener>()
+        callback.onDataActivity(DATA_ACTIVITY_INOUT)
+
+        assertThat(latest).isEqualTo(DATA_ACTIVITY_INOUT.toMobileDataActivityModel())
+    }
+
+    @Test
+    fun carrierId_initialValueCaptured() = runTest {
+        whenever(telephonyManager.simCarrierId).thenReturn(1234)
+
+        val latest by underTest.carrierId.collectLastValue()
+
+        assertThat(latest).isEqualTo(1234)
+    }
+
+    @Test
+    fun carrierId_updatesOnBroadcast() = runTest {
+        whenever(telephonyManager.simCarrierId).thenReturn(1234)
+
+        val latest by underTest.carrierId.collectLastValue()
+
+        fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+            context,
+            carrierIdIntent(carrierId = 4321),
+        )
+
+        assertThat(latest).isEqualTo(4321)
+    }
+
+    @Test
+    fun carrierNetworkChange() = runTest {
+        val latest by underTest.carrierNetworkChangeActive.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.CarrierNetworkListener>()
+        callback.onCarrierNetworkChange(true)
+
+        assertThat(latest).isEqualTo(true)
+    }
+
+    @Test
+    fun networkType_default() = runTest {
+        val latest by underTest.resolvedNetworkType.collectLastValue()
+
+        val expected = UnknownNetworkType
+
+        assertThat(latest).isEqualTo(expected)
+    }
+
+    @Test
+    fun networkType_unknown_hasCorrectKey() = runTest {
+        val latest by underTest.resolvedNetworkType.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
+        val ti =
+            telephonyDisplayInfo(
+                networkType = NETWORK_TYPE_UNKNOWN,
+                overrideNetworkType = NETWORK_TYPE_UNKNOWN,
+            )
+
+        callback.onDisplayInfoChanged(ti)
+
+        val expected = UnknownNetworkType
+        assertThat(latest).isEqualTo(expected)
+        assertThat(latest!!.lookupKey).isEqualTo(MobileMappings.toIconKey(NETWORK_TYPE_UNKNOWN))
+    }
+
+    @Test
+    fun networkType_updatesUsingDefault() = runTest {
+        val latest by underTest.resolvedNetworkType.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
+        val overrideType = OVERRIDE_NETWORK_TYPE_NONE
+        val type = NETWORK_TYPE_LTE
+        val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = overrideType)
+        callback.onDisplayInfoChanged(ti)
+
+        val expected = DefaultNetworkType(mobileMappingsProxy.toIconKey(type))
+        assertThat(latest).isEqualTo(expected)
+    }
+
+    @Test
+    fun networkType_updatesUsingOverride() = runTest {
+        val latest by underTest.resolvedNetworkType.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
+        val type = OVERRIDE_NETWORK_TYPE_LTE_CA
+        val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = type)
+        callback.onDisplayInfoChanged(ti)
+
+        val expected = OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(type))
+        assertThat(latest).isEqualTo(expected)
+    }
+
+    @Test
+    fun networkType_unknownNetworkWithOverride_usesOverrideKey() = runTest {
+        val latest by underTest.resolvedNetworkType.collectLastValue()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
+        val unknown = NETWORK_TYPE_UNKNOWN
+        val type = OVERRIDE_NETWORK_TYPE_LTE_CA
+        val ti = telephonyDisplayInfo(unknown, type)
+        callback.onDisplayInfoChanged(ti)
+
+        val expected = OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(type))
+        assertThat(latest).isEqualTo(expected)
+    }
+
+    @Test
+    fun dataEnabled_initial_false() = runTest {
+        whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
+
+        val latest by underTest.dataEnabled.collectLastValue()
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun isDataEnabled_tracksTelephonyCallback() = runTest {
+        val latest by underTest.dataEnabled.collectLastValue()
+
+        whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
+        assertThat(latest).isFalse()
+
+        val callback = getTelephonyCallbackForType<TelephonyCallback.DataEnabledListener>()
+
+        callback.onDataEnabledChanged(true, 1)
+        assertThat(latest).isTrue()
+
+        callback.onDataEnabledChanged(false, 1)
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun numberOfLevels_isDefault() = runTest {
+        val latest by underTest.numberOfLevels.collectLastValue()
+
+        assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
+    }
+
+    @Test
+    fun roaming_cdma_queriesTelephonyManager() = runTest {
+        val latest by underTest.cdmaRoaming.collectLastValue()
+
+        val cb = getTelephonyCallbackForType<ServiceStateListener>()
+
+        // CDMA roaming is off, GSM roaming is on
+        whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
+        cb.onServiceStateChanged(ServiceState().also { it.roaming = true })
+
+        assertThat(latest).isFalse()
+
+        // CDMA roaming is on, GSM roaming is off
+        whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_ON)
+        cb.onServiceStateChanged(ServiceState().also { it.roaming = false })
+
+        assertThat(latest).isTrue()
+    }
+
+    /**
+     * [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber] returns -1 if the service is
+     * not running or if there is an error while retrieving the cdma ERI
+     */
+    @Test
+    fun cdmaRoaming_ignoresNegativeOne() = runTest {
+        val latest by underTest.cdmaRoaming.collectLastValue()
+
+        val serviceState = ServiceState()
+        serviceState.roaming = false
+
+        val cb = getTelephonyCallbackForType<ServiceStateListener>()
+
+        // CDMA roaming is unavailable (-1), GSM roaming is off
+        whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(-1)
+        cb.onServiceStateChanged(serviceState)
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun roaming_gsm_queriesDisplayInfo_viaDisplayInfo() = runTest {
+        // GIVEN flag is true
+        featureFlagsClassic.fake.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true)
+
+        val latest by underTest.isRoaming.collectLastValue()
+
+        val cb = getTelephonyCallbackForType<DisplayInfoListener>()
+
+        // CDMA roaming is off, GSM roaming is off
+        whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
+        cb.onDisplayInfoChanged(TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, false))
+
+        assertThat(latest).isFalse()
+
+        // CDMA roaming is off, GSM roaming is on
+        cb.onDisplayInfoChanged(TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, true))
+
+        assertThat(latest).isTrue()
+    }
+
+    @Test
+    fun roaming_gsm_queriesDisplayInfo_viaServiceState() = runTest {
+        // GIVEN flag is false
+        featureFlagsClassic.fake.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, false)
+
+        val latest by underTest.isRoaming.collectLastValue()
+
+        val cb = getTelephonyCallbackForType<ServiceStateListener>()
+
+        // CDMA roaming is off, GSM roaming is off
+        whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
+        cb.onServiceStateChanged(ServiceState().also { it.roaming = false })
+
+        assertThat(latest).isFalse()
+
+        // CDMA roaming is off, GSM roaming is on
+        cb.onServiceStateChanged(ServiceState().also { it.roaming = true })
+
+        assertThat(latest).isTrue()
+    }
+
+    @Test
+    fun activity_updatesFromCallback() = runTest {
+        val latest by underTest.dataActivityDirection.collectLastValue()
+
+        assertThat(latest)
+            .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
+
+        val cb = getTelephonyCallbackForType<DataActivityListener>()
+        cb.onDataActivity(DATA_ACTIVITY_IN)
+        assertThat(latest)
+            .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = false))
+
+        cb.onDataActivity(DATA_ACTIVITY_OUT)
+        assertThat(latest)
+            .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = true))
+
+        cb.onDataActivity(DATA_ACTIVITY_INOUT)
+        assertThat(latest).isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true))
+
+        cb.onDataActivity(DATA_ACTIVITY_NONE)
+        assertThat(latest)
+            .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
+
+        cb.onDataActivity(DATA_ACTIVITY_DORMANT)
+        assertThat(latest)
+            .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
+
+        cb.onDataActivity(1234)
+        assertThat(latest)
+            .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
+    }
+
+    @Test
+    fun networkNameForSubId_updates() = runTest {
+        val latest by underTest.carrierName.collectLastValue()
+
+        subscriptionModel.setValue(
             SubscriptionModel(
                 subscriptionId = SUB_1_ID,
                 carrierName = DEFAULT_NAME,
@@ -143,1277 +598,596 @@
             )
         )
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        whenever(telephonyManager.subscriptionId).thenReturn(SUB_1_ID)
+        assertThat(latest?.name).isEqualTo(DEFAULT_NAME)
 
-        underTest =
-            MobileConnectionRepositoryKairosImpl(
-                SUB_1_ID,
-                context,
-                subscriptionModel,
-                DEFAULT_NAME_MODEL,
-                SEP,
-                connectivityManager,
-                telephonyManager,
-                systemUiCarrierConfig,
-                fakeBroadcastDispatcher,
-                mobileMappings,
-                testDispatcher,
-                logger,
-                tableLogger,
-                flags,
-                testScope.backgroundScope,
+        val updatedName = "Derived Carrier"
+        subscriptionModel.setValue(
+            SubscriptionModel(
+                subscriptionId = SUB_1_ID,
+                carrierName = updatedName,
+                profileClass = PROFILE_CLASS_UNSET,
             )
+        )
+
+        assertThat(latest?.name).isEqualTo(updatedName)
     }
 
     @Test
-    fun emergencyOnly() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isEmergencyOnly.onEach { latest = it }.launchIn(this)
+    fun networkNameForSubId_defaultWhenSubscriptionModelNull() = runTest {
+        val latest by underTest.carrierName.collectLastValue()
 
-            val serviceState = ServiceState()
-            serviceState.isEmergencyOnly = true
+        subscriptionModel.setValue(null)
 
-            getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
-
-            assertThat(latest).isEqualTo(true)
-
-            job.cancel()
-        }
+        assertThat(latest?.name).isEqualTo(DEFAULT_NAME)
+    }
 
     @Test
-    fun emergencyOnly_toggles() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isEmergencyOnly.onEach { latest = it }.launchIn(this)
+    fun networkName_default() = runTest {
+        val latest by underTest.networkName.collectLastValue()
 
-            val callback = getTelephonyCallbackForType<ServiceStateListener>()
-            callback.onServiceStateChanged(ServiceState().also { it.isEmergencyOnly = true })
-            assertThat(latest).isTrue()
-
-            callback.onServiceStateChanged(ServiceState().also { it.isEmergencyOnly = false })
-
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
+    }
 
     @Test
-    fun cdmaLevelUpdates() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.cdmaLevel.onEach { latest = it }.launchIn(this)
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_usesBroadcastInfo_returnsDerived() = runTest {
+        val latest by underTest.networkName.collectLastValue()
 
-            val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>()
-            var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true)
-            callback.onSignalStrengthsChanged(strength)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            assertThat(latest).isEqualTo(2)
-
-            // gsmLevel updates, no change to cdmaLevel
-            strength = signalStrength(gsmLevel = 3, cdmaLevel = 2, isGsm = true)
-            callback.onSignalStrengthsChanged(strength)
-
-            assertThat(latest).isEqualTo(2)
-
-            job.cancel()
-        }
+        // spnIntent() sets all values to true and test strings
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun gsmLevelUpdates() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.primaryLevel.onEach { latest = it }.launchIn(this)
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_usesBroadcastInfo_returnsDerived_flagOff() = runTest {
+        val latest by underTest.networkName.collectLastValue()
 
-            val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>()
-            var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true)
-            callback.onSignalStrengthsChanged(strength)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            assertThat(latest).isEqualTo(1)
-
-            strength = signalStrength(gsmLevel = 3, cdmaLevel = 2, isGsm = true)
-            callback.onSignalStrengthsChanged(strength)
-
-            assertThat(latest).isEqualTo(3)
-
-            job.cancel()
-        }
+        // spnIntent() sets all values to true and test strings
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun isGsm() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isGsm.onEach { latest = it }.launchIn(this)
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_broadcastNotForThisSubId_keepsOldValue() = runTest {
+        val latest by underTest.networkName.collectLastValue()
 
-            val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>()
-            var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true)
-            callback.onSignalStrengthsChanged(strength)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            assertThat(latest).isTrue()
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
 
-            strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = false)
-            callback.onSignalStrengthsChanged(strength)
+        // WHEN an intent with a different subId is sent
+        val wrongSubIntent = spnIntent(subId = 101)
 
-            assertThat(latest).isFalse()
+        captor.lastValue.onReceive(context, wrongSubIntent)
 
-            job.cancel()
-        }
+        // THEN the previous intent's name is still used
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun dataConnectionState_connected() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_broadcastNotForThisSubId_keepsOldValue_flagOff() = runTest {
+        val latest by underTest.networkName.collectLastValue()
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(DATA_CONNECTED, 200 /* unused */)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            assertThat(latest).isEqualTo(DataConnectionState.Connected)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
 
-            job.cancel()
-        }
+        // WHEN an intent with a different subId is sent
+        val wrongSubIntent = spnIntent(subId = 101)
+
+        captor.lastValue.onReceive(context, wrongSubIntent)
+
+        // THEN the previous intent's name is still used
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun dataConnectionState_connecting() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_broadcastHasNoData_updatesToDefault() = runTest {
+        val latest by underTest.networkName.collectLastValue()
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(DATA_CONNECTING, 200 /* unused */)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            assertThat(latest).isEqualTo(DataConnectionState.Connecting)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
 
-            job.cancel()
-        }
+        val intentWithoutInfo = spnIntent(showSpn = false, showPlmn = false)
+
+        captor.lastValue.onReceive(context, intentWithoutInfo)
+
+        assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
+    }
 
     @Test
-    fun dataConnectionState_disconnected() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_broadcastHasNoData_updatesToDefault_flagOff() = runTest {
+        val latest by underTest.networkName.collectLastValue()
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(DATA_DISCONNECTED, 200 /* unused */)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            assertThat(latest).isEqualTo(DataConnectionState.Disconnected)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
 
-            job.cancel()
-        }
+        val intentWithoutInfo = spnIntent(showSpn = false, showPlmn = false)
+
+        captor.lastValue.onReceive(context, intentWithoutInfo)
+
+        assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
+    }
 
     @Test
-    fun dataConnectionState_disconnecting() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers() = runTest {
+        // Use the [StateFlow.value] getter so we can prove that the collection happens
+        // even when there is no [Job]
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(DATA_DISCONNECTING, 200 /* unused */)
+        // Starts out default
+        val latest by underTest.networkName.collectLastValue()
+        assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
 
-            assertThat(latest).isEqualTo(DataConnectionState.Disconnecting)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            job.cancel()
-        }
+        // The value is still there despite no active subscribers
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun dataConnectionState_suspended() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers_flagOff() = runTest {
+        // Use the [StateFlow.value] getter so we can prove that the collection happens
+        // even when there is no [Job]
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(DATA_SUSPENDED, 200 /* unused */)
+        // Starts out default
+        val latest by underTest.networkName.collectLastValue()
+        assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
 
-            assertThat(latest).isEqualTo(DataConnectionState.Suspended)
+        val intent = spnIntent()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        captor.lastValue.onReceive(context, intent)
 
-            job.cancel()
-        }
+        // The value is still there despite no active subscribers
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun dataConnectionState_handoverInProgress() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_allFieldsSet_prioritizesDataSpnOverSpn() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(DATA_HANDOVER_IN_PROGRESS, 200 /* unused */)
-
-            assertThat(latest).isEqualTo(DataConnectionState.HandoverInProgress)
-
-            job.cancel()
-        }
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = SPN,
+                dataSpn = DATA_SPN,
+                showPlmn = true,
+                plmn = PLMN,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun dataConnectionState_unknown() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_spnAndPlmn_fallbackToSpnWhenNullDataSpn() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(DATA_UNKNOWN, 200 /* unused */)
-
-            assertThat(latest).isEqualTo(DataConnectionState.Unknown)
-
-            job.cancel()
-        }
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = SPN,
+                dataSpn = null,
+                showPlmn = true,
+                plmn = PLMN,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN"))
+    }
 
     @Test
-    fun dataConnectionState_invalid() =
-        testScope.runTest {
-            var latest: DataConnectionState? = null
-            val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_allFieldsSet_flagOff() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
 
-            val callback =
-                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
-            callback.onDataConnectionStateChanged(45, 200 /* unused */)
-
-            assertThat(latest).isEqualTo(DataConnectionState.Invalid)
-
-            job.cancel()
-        }
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = SPN,
+                dataSpn = DATA_SPN,
+                showPlmn = true,
+                plmn = PLMN,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun dataActivity() =
-        testScope.runTest {
-            var latest: DataActivityModel? = null
-            val job = underTest.dataActivityDirection.onEach { latest = it }.launchIn(this)
-
-            val callback = getTelephonyCallbackForType<DataActivityListener>()
-            callback.onDataActivity(DATA_ACTIVITY_INOUT)
-
-            assertThat(latest).isEqualTo(DATA_ACTIVITY_INOUT.toMobileDataActivityModel())
-
-            job.cancel()
-        }
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = null,
+                dataSpn = DATA_SPN,
+                showPlmn = true,
+                plmn = PLMN,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
     @Test
-    fun carrierId_initialValueCaptured() =
-        testScope.runTest {
-            whenever(telephonyManager.simCarrierId).thenReturn(1234)
-
-            var latest: Int? = null
-            val job = underTest.carrierId.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEqualTo(1234)
-
-            job.cancel()
-        }
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_showPlmn_plmnNotNull_showSpn_spnNotNull_dataSpnNull() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = SPN,
+                dataSpn = null,
+                showPlmn = true,
+                plmn = PLMN,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN"))
+    }
 
     @Test
-    fun carrierId_updatesOnBroadcast() =
-        testScope.runTest {
-            whenever(telephonyManager.simCarrierId).thenReturn(1234)
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull_flagOff() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = null,
+                dataSpn = DATA_SPN,
+                showPlmn = true,
+                plmn = PLMN,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
+    }
 
-            var latest: Int? = null
-            val job = underTest.carrierId.onEach { latest = it }.launchIn(this)
+    @Test
+    fun networkName_showPlmn_noShowSPN() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = false,
+                spn = SPN,
+                dataSpn = DATA_SPN,
+                showPlmn = true,
+                plmn = PLMN,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN"))
+    }
 
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
-                carrierIdIntent(carrierId = 4321),
+    @Test
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_showPlmn_plmnNull_showSpn() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = SPN,
+                dataSpn = DATA_SPN,
+                showPlmn = true,
+                plmn = null,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$DATA_SPN"))
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_showPlmn_plmnNull_showSpn_dataSpnNull() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = SPN,
+                dataSpn = null,
+                showPlmn = true,
+                plmn = null,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$SPN"))
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_showPlmn_plmnNull_showSpn_bothSpnNull() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = null,
+                dataSpn = null,
+                showPlmn = true,
+                plmn = null,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
+    fun networkName_showPlmn_plmnNull_showSpn_flagOff() = runTest {
+        val latest by underTest.networkName.collectLastValue()
+        val captor = argumentCaptor<BroadcastReceiver>()
+        verify(context).registerReceiver(captor.capture(), any())
+        val intent =
+            spnIntent(
+                subId = SUB_1_ID,
+                showSpn = true,
+                spn = SPN,
+                dataSpn = DATA_SPN,
+                showPlmn = true,
+                plmn = null,
+            )
+        captor.lastValue.onReceive(context, intent)
+        assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$DATA_SPN"))
+    }
+
+    @Test
+    fun operatorAlphaShort_tracked() = runTest {
+        val latest by underTest.operatorAlphaShort.collectLastValue()
+
+        val shortName = "short name"
+        val serviceState = ServiceState()
+        serviceState.setOperatorName(
+            /* longName */ "long name",
+            /* shortName */ shortName,
+            /* numeric */ "12345",
+        )
+
+        getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
+
+        assertThat(latest).isEqualTo(shortName)
+    }
+
+    @Test
+    fun isInService_notIwlan() = runTest {
+        val latest by underTest.isInService.collectLastValue()
+
+        val nriInService =
+            NetworkRegistrationInfo.Builder()
+                .setDomain(DOMAIN_PS)
+                .setTransportType(TRANSPORT_TYPE_WWAN)
+                .setRegistrationState(REGISTRATION_STATE_HOME)
+                .build()
+
+        getTelephonyCallbackForType<ServiceStateListener>()
+            .onServiceStateChanged(
+                ServiceState().also {
+                    it.voiceRegState = STATE_IN_SERVICE
+                    it.addNetworkRegistrationInfo(nriInService)
+                }
             )
 
-            assertThat(latest).isEqualTo(4321)
+        assertThat(latest).isTrue()
 
-            job.cancel()
-        }
-
-    @Test
-    fun carrierNetworkChange() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.carrierNetworkChangeActive.onEach { latest = it }.launchIn(this)
-
-            val callback = getTelephonyCallbackForType<TelephonyCallback.CarrierNetworkListener>()
-            callback.onCarrierNetworkChange(true)
-
-            assertThat(latest).isEqualTo(true)
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkType_default() =
-        testScope.runTest {
-            var latest: ResolvedNetworkType? = null
-            val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
-
-            val expected = UnknownNetworkType
-
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkType_unknown_hasCorrectKey() =
-        testScope.runTest {
-            var latest: ResolvedNetworkType? = null
-            val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
-
-            val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
-            val ti =
-                telephonyDisplayInfo(
-                    networkType = NETWORK_TYPE_UNKNOWN,
-                    overrideNetworkType = NETWORK_TYPE_UNKNOWN,
-                )
-
-            callback.onDisplayInfoChanged(ti)
-
-            val expected = UnknownNetworkType
-            assertThat(latest).isEqualTo(expected)
-            assertThat(latest!!.lookupKey).isEqualTo(MobileMappings.toIconKey(NETWORK_TYPE_UNKNOWN))
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkType_updatesUsingDefault() =
-        testScope.runTest {
-            var latest: ResolvedNetworkType? = null
-            val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
-
-            val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
-            val overrideType = OVERRIDE_NETWORK_TYPE_NONE
-            val type = NETWORK_TYPE_LTE
-            val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = overrideType)
-            callback.onDisplayInfoChanged(ti)
-
-            val expected = DefaultNetworkType(mobileMappings.toIconKey(type))
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkType_updatesUsingOverride() =
-        testScope.runTest {
-            var latest: ResolvedNetworkType? = null
-            val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
-
-            val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
-            val type = OVERRIDE_NETWORK_TYPE_LTE_CA
-            val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = type)
-            callback.onDisplayInfoChanged(ti)
-
-            val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkType_unknownNetworkWithOverride_usesOverrideKey() =
-        testScope.runTest {
-            var latest: ResolvedNetworkType? = null
-            val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
-
-            val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
-            val unknown = NETWORK_TYPE_UNKNOWN
-            val type = OVERRIDE_NETWORK_TYPE_LTE_CA
-            val ti = telephonyDisplayInfo(unknown, type)
-            callback.onDisplayInfoChanged(ti)
-
-            val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
-
-    @Test
-    fun dataEnabled_initial_false() =
-        testScope.runTest {
-            whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
-
-            assertThat(underTest.dataEnabled.value).isFalse()
-        }
-
-    @Test
-    fun isDataEnabled_tracksTelephonyCallback() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
-
-            whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
-            assertThat(underTest.dataEnabled.value).isFalse()
-
-            val callback = getTelephonyCallbackForType<TelephonyCallback.DataEnabledListener>()
-
-            callback.onDataEnabledChanged(true, 1)
-            assertThat(latest).isTrue()
-
-            callback.onDataEnabledChanged(false, 1)
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
-
-    @Test
-    fun numberOfLevels_isDefault() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
-
-            job.cancel()
-        }
-
-    @Test
-    fun roaming_cdma_queriesTelephonyManager() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this)
-
-            val cb = getTelephonyCallbackForType<ServiceStateListener>()
-
-            // CDMA roaming is off, GSM roaming is on
-            whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
-            cb.onServiceStateChanged(ServiceState().also { it.roaming = true })
-
-            assertThat(latest).isFalse()
-
-            // CDMA roaming is on, GSM roaming is off
-            whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_ON)
-            cb.onServiceStateChanged(ServiceState().also { it.roaming = false })
-
-            assertThat(latest).isTrue()
-
-            job.cancel()
-        }
-
-    /**
-     * [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber] returns -1 if the service is
-     * not running or if there is an error while retrieving the cdma ERI
-     */
-    @Test
-    fun cdmaRoaming_ignoresNegativeOne() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this)
-
-            val serviceState = ServiceState()
-            serviceState.roaming = false
-
-            val cb = getTelephonyCallbackForType<ServiceStateListener>()
-
-            // CDMA roaming is unavailable (-1), GSM roaming is off
-            whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(-1)
-            cb.onServiceStateChanged(serviceState)
-
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
-
-    @Test
-    fun roaming_gsm_queriesDisplayInfo_viaDisplayInfo() =
-        testScope.runTest {
-            // GIVEN flag is true
-            flags.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true)
-
-            // Re-create the repository, because the flag is read at init
-            underTest =
-                MobileConnectionRepositoryKairosImpl(
-                    SUB_1_ID,
-                    context,
-                    subscriptionModel,
-                    DEFAULT_NAME_MODEL,
-                    SEP,
-                    connectivityManager,
-                    telephonyManager,
-                    systemUiCarrierConfig,
-                    fakeBroadcastDispatcher,
-                    mobileMappings,
-                    testDispatcher,
-                    logger,
-                    tableLogger,
-                    flags,
-                    testScope.backgroundScope,
-                )
-
-            var latest: Boolean? = null
-            val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
-
-            val cb = getTelephonyCallbackForType<DisplayInfoListener>()
-
-            // CDMA roaming is off, GSM roaming is off
-            whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
-            cb.onDisplayInfoChanged(
-                TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, false, false, false)
-            )
-
-            assertThat(latest).isFalse()
-
-            // CDMA roaming is off, GSM roaming is on
-            cb.onDisplayInfoChanged(
-                TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, true, false, false)
-            )
-
-            assertThat(latest).isTrue()
-
-            job.cancel()
-        }
-
-    @Test
-    fun roaming_gsm_queriesDisplayInfo_viaServiceState() =
-        testScope.runTest {
-            // GIVEN flag is false
-            flags.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, false)
-
-            // Re-create the repository, because the flag is read at init
-            underTest =
-                MobileConnectionRepositoryKairosImpl(
-                    SUB_1_ID,
-                    context,
-                    subscriptionModel,
-                    DEFAULT_NAME_MODEL,
-                    SEP,
-                    connectivityManager,
-                    telephonyManager,
-                    systemUiCarrierConfig,
-                    fakeBroadcastDispatcher,
-                    mobileMappings,
-                    testDispatcher,
-                    logger,
-                    tableLogger,
-                    flags,
-                    testScope.backgroundScope,
-                )
-
-            var latest: Boolean? = null
-            val job = underTest.isRoaming.onEach { latest = it }.launchIn(this)
-
-            val cb = getTelephonyCallbackForType<ServiceStateListener>()
-
-            // CDMA roaming is off, GSM roaming is off
-            whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF)
-            cb.onServiceStateChanged(ServiceState().also { it.roaming = false })
-
-            assertThat(latest).isFalse()
-
-            // CDMA roaming is off, GSM roaming is on
-            cb.onServiceStateChanged(ServiceState().also { it.roaming = true })
-
-            assertThat(latest).isTrue()
-
-            job.cancel()
-        }
-
-    @Test
-    fun activity_updatesFromCallback() =
-        testScope.runTest {
-            var latest: DataActivityModel? = null
-            val job = underTest.dataActivityDirection.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest)
-                .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
-
-            val cb = getTelephonyCallbackForType<DataActivityListener>()
-            cb.onDataActivity(DATA_ACTIVITY_IN)
-            assertThat(latest)
-                .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = false))
-
-            cb.onDataActivity(DATA_ACTIVITY_OUT)
-            assertThat(latest)
-                .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = true))
-
-            cb.onDataActivity(DATA_ACTIVITY_INOUT)
-            assertThat(latest)
-                .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true))
-
-            cb.onDataActivity(DATA_ACTIVITY_NONE)
-            assertThat(latest)
-                .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
-
-            cb.onDataActivity(DATA_ACTIVITY_DORMANT)
-            assertThat(latest)
-                .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
-
-            cb.onDataActivity(1234)
-            assertThat(latest)
-                .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkNameForSubId_updates() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.carrierName.onEach { latest = it }.launchIn(this)
-
-            subscriptionModel.value =
-                SubscriptionModel(
-                    subscriptionId = SUB_1_ID,
-                    carrierName = DEFAULT_NAME,
-                    profileClass = PROFILE_CLASS_UNSET,
-                )
-
-            assertThat(latest?.name).isEqualTo(DEFAULT_NAME)
-
-            val updatedName = "Derived Carrier"
-            subscriptionModel.value =
-                SubscriptionModel(
-                    subscriptionId = SUB_1_ID,
-                    carrierName = updatedName,
-                    profileClass = PROFILE_CLASS_UNSET,
-                )
-
-            assertThat(latest?.name).isEqualTo(updatedName)
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkNameForSubId_defaultWhenSubscriptionModelNull() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.carrierName.onEach { latest = it }.launchIn(this)
-
-            subscriptionModel.value = null
-
-            assertThat(latest?.name).isEqualTo(DEFAULT_NAME)
-
-            job.cancel()
-        }
-
-    @Test
-    fun networkName_default() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
-
-            job.cancel()
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_usesBroadcastInfo_returnsDerived() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            // spnIntent() sets all values to true and test strings
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            job.cancel()
-        }
-
-    @Test
-    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_usesBroadcastInfo_returnsDerived_flagOff() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            // spnIntent() sets all values to true and test strings
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            job.cancel()
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_broadcastNotForThisSubId_keepsOldValue() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            // WHEN an intent with a different subId is sent
-            val wrongSubIntent = spnIntent(subId = 101)
-
-            captor.lastValue.onReceive(context, wrongSubIntent)
-
-            // THEN the previous intent's name is still used
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            job.cancel()
-        }
-
-    @Test
-    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_broadcastNotForThisSubId_keepsOldValue_flagOff() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            // WHEN an intent with a different subId is sent
-            val wrongSubIntent = spnIntent(subId = 101)
-
-            captor.lastValue.onReceive(context, wrongSubIntent)
-
-            // THEN the previous intent's name is still used
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            job.cancel()
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_broadcastHasNoData_updatesToDefault() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            val intentWithoutInfo = spnIntent(showSpn = false, showPlmn = false)
-
-            captor.lastValue.onReceive(context, intentWithoutInfo)
-
-            assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
-
-            job.cancel()
-        }
-
-    @Test
-    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_broadcastHasNoData_updatesToDefault_flagOff() =
-        testScope.runTest {
-            var latest: NetworkNameModel? = null
-            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-
-            val intentWithoutInfo = spnIntent(showSpn = false, showPlmn = false)
-
-            captor.lastValue.onReceive(context, intentWithoutInfo)
-
-            assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
-
-            job.cancel()
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers() =
-        testScope.runTest {
-            // Use the [StateFlow.value] getter so we can prove that the collection happens
-            // even when there is no [Job]
-
-            // Starts out default
-            assertThat(underTest.networkName.value).isEqualTo(DEFAULT_NAME_MODEL)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            // The value is still there despite no active subscribers
-            assertThat(underTest.networkName.value)
-                .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-        }
-
-    @Test
-    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers_flagOff() =
-        testScope.runTest {
-            // Use the [StateFlow.value] getter so we can prove that the collection happens
-            // even when there is no [Job]
-
-            // Starts out default
-            assertThat(underTest.networkName.value).isEqualTo(DEFAULT_NAME_MODEL)
-
-            val intent = spnIntent()
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            captor.lastValue.onReceive(context, intent)
-
-            // The value is still there despite no active subscribers
-            assertThat(underTest.networkName.value)
-                .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_allFieldsSet_prioritizesDataSpnOverSpn() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = SPN,
-                    dataSpn = DATA_SPN,
-                    showPlmn = true,
-                    plmn = PLMN,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_spnAndPlmn_fallbackToSpnWhenNullDataSpn() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = SPN,
-                    dataSpn = null,
-                    showPlmn = true,
-                    plmn = PLMN,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN"))
-        }
-
-    @Test
-    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_allFieldsSet_flagOff() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = SPN,
-                    dataSpn = DATA_SPN,
-                    showPlmn = true,
-                    plmn = PLMN,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = null,
-                    dataSpn = DATA_SPN,
-                    showPlmn = true,
-                    plmn = PLMN,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_showPlmn_plmnNotNull_showSpn_spnNotNull_dataSpnNull() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = SPN,
-                    dataSpn = null,
-                    showPlmn = true,
-                    plmn = PLMN,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN"))
-        }
-
-    @Test
-    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull_flagOff() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = null,
-                    dataSpn = DATA_SPN,
-                    showPlmn = true,
-                    plmn = PLMN,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN"))
-        }
-
-    @Test
-    fun networkName_showPlmn_noShowSPN() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = false,
-                    spn = SPN,
-                    dataSpn = DATA_SPN,
-                    showPlmn = true,
-                    plmn = PLMN,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN"))
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_showPlmn_plmnNull_showSpn() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = SPN,
-                    dataSpn = DATA_SPN,
-                    showPlmn = true,
-                    plmn = null,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$DATA_SPN"))
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_showPlmn_plmnNull_showSpn_dataSpnNull() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = SPN,
-                    dataSpn = null,
-                    showPlmn = true,
-                    plmn = null,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$SPN"))
-        }
-
-    @Test
-    @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_showPlmn_plmnNull_showSpn_bothSpnNull() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = null,
-                    dataSpn = null,
-                    showPlmn = true,
-                    plmn = null,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL)
-        }
-
-    @Test
-    @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN)
-    fun networkName_showPlmn_plmnNull_showSpn_flagOff() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.networkName)
-            val captor = argumentCaptor<BroadcastReceiver>()
-            verify(context).registerReceiver(captor.capture(), any())
-            val intent =
-                spnIntent(
-                    subId = SUB_1_ID,
-                    showSpn = true,
-                    spn = SPN,
-                    dataSpn = DATA_SPN,
-                    showPlmn = true,
-                    plmn = null,
-                )
-            captor.lastValue.onReceive(context, intent)
-            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$DATA_SPN"))
-        }
-
-    @Test
-    fun operatorAlphaShort_tracked() =
-        testScope.runTest {
-            var latest: String? = null
-
-            val job = underTest.operatorAlphaShort.onEach { latest = it }.launchIn(this)
-
-            val shortName = "short name"
-            val serviceState = ServiceState()
-            serviceState.setOperatorName(
-                /* longName */ "long name",
-                /* shortName */ shortName,
-                /* numeric */ "12345",
-            )
-
-            getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
-
-            assertThat(latest).isEqualTo(shortName)
-
-            job.cancel()
-        }
-
-    @Test
-    fun isInService_notIwlan() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isInService.onEach { latest = it }.launchIn(this)
-
-            val nriInService =
-                NetworkRegistrationInfo.Builder()
-                    .setDomain(DOMAIN_PS)
-                    .setTransportType(TRANSPORT_TYPE_WWAN)
-                    .setRegistrationState(REGISTRATION_STATE_HOME)
-                    .build()
-
-            getTelephonyCallbackForType<ServiceStateListener>()
-                .onServiceStateChanged(
-                    ServiceState().also {
-                        it.voiceRegState = STATE_IN_SERVICE
-                        it.addNetworkRegistrationInfo(nriInService)
-                    }
-                )
-
-            assertThat(latest).isTrue()
-
-            getTelephonyCallbackForType<ServiceStateListener>()
-                .onServiceStateChanged(
-                    ServiceState().also {
-                        it.voiceRegState = STATE_OUT_OF_SERVICE
-                        it.addNetworkRegistrationInfo(nriInService)
-                    }
-                )
-            assertThat(latest).isTrue()
-
-            val nriNotInService =
-                NetworkRegistrationInfo.Builder()
-                    .setDomain(DOMAIN_PS)
-                    .setTransportType(TRANSPORT_TYPE_WWAN)
-                    .setRegistrationState(REGISTRATION_STATE_DENIED)
-                    .build()
-            getTelephonyCallbackForType<ServiceStateListener>()
-                .onServiceStateChanged(
-                    ServiceState().also {
-                        it.voiceRegState = STATE_OUT_OF_SERVICE
-                        it.addNetworkRegistrationInfo(nriNotInService)
-                    }
-                )
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
-
-    @Test
-    fun isInService_isIwlan_voiceOutOfService_dataInService() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isInService.onEach { latest = it }.launchIn(this)
-
-            val iwlanData =
-                NetworkRegistrationInfo.Builder()
-                    .setDomain(DOMAIN_PS)
-                    .setTransportType(TRANSPORT_TYPE_WLAN)
-                    .setRegistrationState(REGISTRATION_STATE_HOME)
-                    .build()
-            val serviceState =
+        getTelephonyCallbackForType<ServiceStateListener>()
+            .onServiceStateChanged(
                 ServiceState().also {
                     it.voiceRegState = STATE_OUT_OF_SERVICE
-                    it.addNetworkRegistrationInfo(iwlanData)
+                    it.addNetworkRegistrationInfo(nriInService)
                 }
-
-            getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
-
-    @Test
-    fun isNonTerrestrial_updatesFromCallback0() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.isNonTerrestrial)
-
-            // Starts out false
-            assertThat(latest).isFalse()
-
-            val callback = getTelephonyCallbackForType<CarrierRoamingNtnListener>()
-
-            callback.onCarrierRoamingNtnModeChanged(true)
-            assertThat(latest).isTrue()
-
-            callback.onCarrierRoamingNtnModeChanged(false)
-            assertThat(latest).isFalse()
-        }
-
-    @Test
-    fun numberOfLevels_usesCarrierConfig() =
-        testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
-
-            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
-
-            systemUiCarrierConfig.processNewCarrierConfig(
-                testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true)
             )
+        assertThat(latest).isTrue()
 
-            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS + 1)
-
-            systemUiCarrierConfig.processNewCarrierConfig(
-                testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)
+        val nriNotInService =
+            NetworkRegistrationInfo.Builder()
+                .setDomain(DOMAIN_PS)
+                .setTransportType(TRANSPORT_TYPE_WWAN)
+                .setRegistrationState(REGISTRATION_STATE_DENIED)
+                .build()
+        getTelephonyCallbackForType<ServiceStateListener>()
+            .onServiceStateChanged(
+                ServiceState().also {
+                    it.voiceRegState = STATE_OUT_OF_SERVICE
+                    it.addNetworkRegistrationInfo(nriNotInService)
+                }
             )
-
-            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
-
-            job.cancel()
-        }
-
-    @Test
-    fun inflateSignalStrength_usesCarrierConfig() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.inflateSignalStrength)
-
-            assertThat(latest).isEqualTo(false)
-
-            systemUiCarrierConfig.processNewCarrierConfig(
-                testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true)
-            )
-
-            assertThat(latest).isEqualTo(true)
-
-            systemUiCarrierConfig.processNewCarrierConfig(
-                testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)
-            )
-
-            assertThat(latest).isEqualTo(false)
-        }
-
-    @Test
-    fun allowNetworkSliceIndicator_exposesCarrierConfigValue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.allowNetworkSliceIndicator)
-
-            systemUiCarrierConfig.processNewCarrierConfig(
-                testCarrierConfigWithOverride(KEY_SHOW_5G_SLICE_ICON_BOOL, true)
-            )
-
-            assertThat(latest).isTrue()
-
-            systemUiCarrierConfig.processNewCarrierConfig(
-                testCarrierConfigWithOverride(KEY_SHOW_5G_SLICE_ICON_BOOL, false)
-            )
-
-            assertThat(latest).isFalse()
-        }
-
-    @Test
-    fun isAllowedDuringAirplaneMode_alwaysFalse() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode)
-
-            assertThat(latest).isFalse()
-        }
-
-    @Test
-    fun hasPrioritizedCaps_defaultFalse() {
-        assertThat(underTest.hasPrioritizedNetworkCapabilities.value).isFalse()
+        assertThat(latest).isFalse()
     }
 
     @Test
-    fun hasPrioritizedCaps_trueWhenAvailable() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.hasPrioritizedNetworkCapabilities)
+    fun isInService_isIwlan_voiceOutOfService_dataInService() = runTest {
+        val latest by underTest.isInService.collectLastValue()
 
-            val callback: NetworkCallback =
-                withArgCaptor<NetworkCallback> {
-                    verify(connectivityManager).registerNetworkCallback(any(), capture())
-                }
+        val iwlanData =
+            NetworkRegistrationInfo.Builder()
+                .setDomain(DOMAIN_PS)
+                .setTransportType(TRANSPORT_TYPE_WLAN)
+                .setRegistrationState(REGISTRATION_STATE_HOME)
+                .build()
+        val serviceState =
+            ServiceState().also {
+                it.voiceRegState = STATE_OUT_OF_SERVICE
+                it.addNetworkRegistrationInfo(iwlanData)
+            }
 
-            callback.onAvailable(mock())
-
-            assertThat(latest).isTrue()
-        }
+        getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState)
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun hasPrioritizedCaps_becomesFalseWhenNetworkLost() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.hasPrioritizedNetworkCapabilities)
+    fun isNonTerrestrial_updatesFromCallback0() = runTest {
+        val latest by underTest.isNonTerrestrial.collectLastValue()
 
-            val callback: NetworkCallback =
-                withArgCaptor<NetworkCallback> {
-                    verify(connectivityManager).registerNetworkCallback(any(), capture())
-                }
+        // Starts out false
+        assertThat(latest).isFalse()
 
-            callback.onAvailable(mock())
+        val callback = getTelephonyCallbackForType<CarrierRoamingNtnListener>()
 
-            assertThat(latest).isTrue()
+        callback.onCarrierRoamingNtnModeChanged(true)
+        assertThat(latest).isTrue()
 
-            callback.onLost(mock())
+        callback.onCarrierRoamingNtnModeChanged(false)
+        assertThat(latest).isFalse()
+    }
 
-            assertThat(latest).isFalse()
-        }
+    @Test
+    fun numberOfLevels_usesCarrierConfig() = runTest {
+        val latest by underTest.numberOfLevels.collectLastValue()
 
-    private inline fun <reified T> getTelephonyCallbackForType(): T {
+        assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
+
+        systemUiCarrierConfig.processNewCarrierConfig(
+            testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true)
+        )
+
+        assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS + 1)
+
+        systemUiCarrierConfig.processNewCarrierConfig(
+            testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)
+        )
+
+        assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
+    }
+
+    @Test
+    fun inflateSignalStrength_usesCarrierConfig() = runTest {
+        val latest by underTest.inflateSignalStrength.collectLastValue()
+
+        assertThat(latest).isEqualTo(false)
+
+        systemUiCarrierConfig.processNewCarrierConfig(
+            testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true)
+        )
+
+        assertThat(latest).isEqualTo(true)
+
+        systemUiCarrierConfig.processNewCarrierConfig(
+            testCarrierConfigWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)
+        )
+
+        assertThat(latest).isEqualTo(false)
+    }
+
+    @Test
+    fun allowNetworkSliceIndicator_exposesCarrierConfigValue() = runTest {
+        val latest by underTest.allowNetworkSliceIndicator.collectLastValue()
+
+        systemUiCarrierConfig.processNewCarrierConfig(
+            testCarrierConfigWithOverride(KEY_SHOW_5G_SLICE_ICON_BOOL, true)
+        )
+
+        assertThat(latest).isTrue()
+
+        systemUiCarrierConfig.processNewCarrierConfig(
+            testCarrierConfigWithOverride(KEY_SHOW_5G_SLICE_ICON_BOOL, false)
+        )
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun isAllowedDuringAirplaneMode_alwaysFalse() = runTest {
+        val latest by underTest.isAllowedDuringAirplaneMode.collectLastValue()
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun hasPrioritizedCaps_defaultFalse() = runTest {
+        // stand up under-test to kick-off activation
+        underTest
+
+        assertThat(kairos.transact { underTest.hasPrioritizedNetworkCapabilities.sample() })
+            .isFalse()
+    }
+
+    @Test
+    fun hasPrioritizedCaps_trueWhenAvailable() = runTest {
+        val latest by underTest.hasPrioritizedNetworkCapabilities.collectLastValue()
+
+        val callback: NetworkCallback =
+            argumentCaptor<NetworkCallback>()
+                .apply { verify(connectivityManager).registerNetworkCallback(any(), capture()) }
+                .lastValue
+
+        callback.onAvailable(mock())
+
+        assertThat(latest).isTrue()
+    }
+
+    @Test
+    fun hasPrioritizedCaps_becomesFalseWhenNetworkLost() = runTest {
+        val latest by underTest.hasPrioritizedNetworkCapabilities.collectLastValue()
+
+        val callback: NetworkCallback =
+            argumentCaptor<NetworkCallback>()
+                .apply { verify(connectivityManager).registerNetworkCallback(any(), capture()) }
+                .lastValue
+
+        callback.onAvailable(mock())
+
+        assertThat(latest).isTrue()
+
+        callback.onLost(mock())
+
+        assertThat(latest).isFalse()
+    }
+
+    private inline fun <reified T> Kosmos.getTelephonyCallbackForType(): T {
         return MobileTelephonyHelpers.getTelephonyCallbackForType(telephonyManager)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosTest.kt
index 85423218..e04a96e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
 
 import android.annotation.SuppressLint
 import android.content.Intent
+import android.content.applicationContext
+import android.content.testableContext
 import android.net.ConnectivityManager
 import android.net.Network
 import android.net.NetworkCapabilities
@@ -25,6 +27,7 @@
 import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
 import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
 import android.net.NetworkCapabilities.TRANSPORT_WIFI
+import android.net.connectivityManager
 import android.net.vcn.VcnTransportInfo
 import android.net.wifi.WifiInfo
 import android.net.wifi.WifiManager
@@ -34,1154 +37,894 @@
 import android.telephony.SubscriptionInfo
 import android.telephony.SubscriptionManager
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
-import android.telephony.TelephonyCallback
 import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener
+import android.telephony.TelephonyCallback.EmergencyCallbackModeListener
 import android.telephony.TelephonyManager
+import android.telephony.telephonyManager
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.telephony.PhoneConstants
-import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.keyguard.keyguardUpdateMonitor
 import com.android.settingslib.R
 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.broadcast.broadcastDispatcher
+import com.android.systemui.broadcast.broadcastDispatcherContext
 import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.log.table.logcatTableLogBuffer
 import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.airplaneModeRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.carrierConfigRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairosImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.getTelephonyCallbackForType
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.subscriptionManager
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.subscriptionManagerProxy
+import com.android.systemui.statusbar.pipeline.mobile.util.fake
 import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots
-import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.wifiRepository
 import com.android.systemui.testKosmos
-import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.user.data.repository.userRepository
 import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.mockito.argumentCaptor
-import com.android.systemui.util.mockito.capture
-import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.wifitrackerlib.MergedCarrierEntry
 import com.android.wifitrackerlib.WifiEntry
 import com.android.wifitrackerlib.WifiPickerTracker
 import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
 import java.util.UUID
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Ignore
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.anyString
-import org.mockito.Mock
+import org.mockito.Mockito
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.stub
 import org.mockito.kotlin.whenever
 
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 // This is required because our [SubscriptionManager.OnSubscriptionsChangedListener] uses a looper
 // to run the callback and this makes the looper place nicely with TestScope etc.
 @TestableLooper.RunWithLooper
+@RunWith(AndroidJUnit4::class)
 class MobileConnectionsRepositoryKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
 
-    private val flags =
-        FakeFeatureFlagsClassic().also { it.set(Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) }
+    private val Kosmos.wifiManager: WifiManager by Fixture { mock {} }
+    private val Kosmos.wifiPickerTrackerFactory: WifiPickerTrackerFactory by Fixture {
+        mock {
+            on { create(any(), any(), wifiPickerTrackerCallback.capture(), any()) } doReturn
+                wifiPickerTracker
+        }
+    }
+    private val Kosmos.wifiPickerTracker: WifiPickerTracker by Fixture { mock {} }
+    private val Kosmos.wifiTableLogBuffer by Fixture { logcatTableLogBuffer(this, "wifiTableLog") }
 
-    private lateinit var connectionFactory: MobileConnectionRepositoryImpl.Factory
-    private lateinit var carrierMergedFactory: CarrierMergedConnectionRepository.Factory
-    private lateinit var fullConnectionFactory: FullMobileConnectionRepository.Factory
-    private lateinit var connectivityRepository: ConnectivityRepository
-    private lateinit var airplaneModeRepository: FakeAirplaneModeRepository
-    private lateinit var wifiRepository: WifiRepository
-    private lateinit var carrierConfigRepository: CarrierConfigRepository
-
-    @Mock private lateinit var connectivityManager: ConnectivityManager
-    @Mock private lateinit var subscriptionManager: SubscriptionManager
-    @Mock private lateinit var telephonyManager: TelephonyManager
-    @Mock private lateinit var logger: MobileInputLogger
-    private val summaryLogger = logcatTableLogBuffer(kosmos, "summaryLogger")
-    @Mock private lateinit var logBufferFactory: TableLogBufferFactory
-    @Mock private lateinit var updateMonitor: KeyguardUpdateMonitor
-    @Mock private lateinit var wifiManager: WifiManager
-    @Mock private lateinit var wifiPickerTrackerFactory: WifiPickerTrackerFactory
-    @Mock private lateinit var wifiPickerTracker: WifiPickerTracker
-    private val wifiTableLogBuffer = logcatTableLogBuffer(kosmos, "wifiTableLog")
-
-    private val mobileMappings = FakeMobileMappingsProxy()
-    private val subscriptionManagerProxy = FakeSubscriptionManagerProxy()
     private val mainExecutor = FakeExecutor(FakeSystemClock())
     private val wifiLogBuffer = LogBuffer("wifi", maxSize = 100, logcatEchoTracker = mock())
     private val wifiPickerTrackerCallback =
         argumentCaptor<WifiPickerTracker.WifiPickerTrackerCallback>()
     private val vcnTransportInfo = VcnTransportInfo.Builder().build()
-    private val userRepository = kosmos.fakeUserRepository
 
-    private val testDispatcher = StandardTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private val Kosmos.underTest
+        get() = mobileConnectionsRepositoryKairosImpl
 
-    private lateinit var underTest: MobileConnectionsRepositoryKairosImpl
+    private val kosmos =
+        testKosmos().apply {
+            fakeFeatureFlagsClassic.set(Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO, true)
+            broadcastDispatcherContext = testableContext
+            connectivityRepository =
+                ConnectivityRepositoryImpl(
+                    connectivityManager,
+                    ConnectivitySlots(applicationContext),
+                    applicationContext,
+                    mock(),
+                    mock(),
+                    applicationCoroutineScope,
+                    mock(),
+                )
+            wifiRepository =
+                WifiRepositoryImpl(
+                    applicationContext,
+                    userRepository,
+                    applicationCoroutineScope,
+                    mainExecutor,
+                    testDispatcher,
+                    wifiPickerTrackerFactory,
+                    wifiManager,
+                    wifiLogBuffer,
+                    wifiTableLogBuffer,
+                )
+            subscriptionManager.stub {
+                // For convenience, set up the subscription info callbacks
+                on { getActiveSubscriptionInfo(anyInt()) } doAnswer
+                    { invocation ->
+                        when (invocation.getArgument(0) as Int) {
+                            1 -> SUB_1
+                            2 -> SUB_2
+                            3 -> SUB_3
+                            4 -> SUB_4
+                            else -> null
+                        }
+                    }
+            }
+            telephonyManager.stub {
+                on { simOperatorName } doReturn ""
+                // Set up so the individual connection repositories
+                on { createForSubscriptionId(anyInt()) } doAnswer
+                    { invocation ->
+                        telephonyManager.stub {
+                            on { subscriptionId } doReturn invocation.getArgument(0)
+                        }
+                    }
+            }
+            testScope.runCurrent()
+        }
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        whenever(telephonyManager.simOperatorName).thenReturn("")
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
-        // Set up so the individual connection repositories
-        whenever(telephonyManager.createForSubscriptionId(anyInt())).thenAnswer { invocation ->
-            telephonyManager.also {
-                whenever(it.subscriptionId).thenReturn(invocation.getArgument(0))
+    @Test
+    fun testSubscriptions_initiallyEmpty() = runTest {
+        assertThat(underTest.subscriptions.collectLastValue().value)
+            .isEqualTo(listOf<SubscriptionModel>())
+    }
+
+    @Test
+    fun testSubscriptions_listUpdates() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1, SUB_2)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
+    }
+
+    @Test
+    fun testSubscriptions_removingSub_updatesList() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        // WHEN 2 networks show up
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1, SUB_2)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        // WHEN one network is removed
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_2)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        // THEN the subscriptions list represents the newest change
+        assertThat(latest).isEqualTo(listOf(MODEL_2))
+    }
+
+    @Test
+    fun subscriptions_subIsOnlyNtn_modelHasExclusivelyNtnTrue() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        val onlyNtnSub =
+            mock<SubscriptionInfo> {
+                on { isOnlyNonTerrestrialNetwork } doReturn true
+                on { subscriptionId } doReturn 45
+                on { groupUuid } doReturn GROUP_1
+                on { carrierName } doReturn "NTN only"
+                on { profileClass } doReturn PROFILE_CLASS_UNSET
+            }
+
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(onlyNtnSub)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!![0].isExclusivelyNonTerrestrial).isTrue()
+    }
+
+    @Test
+    fun subscriptions_subIsNotOnlyNtn_modelHasExclusivelyNtnFalse() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        val notOnlyNtnSub =
+            mock<SubscriptionInfo> {
+                on { isOnlyNonTerrestrialNetwork } doReturn false
+                on { subscriptionId } doReturn 45
+                on { groupUuid } doReturn GROUP_1
+                on { carrierName } doReturn "NTN only"
+                on { profileClass } doReturn PROFILE_CLASS_UNSET
+            }
+
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(notOnlyNtnSub)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        assertThat(latest).hasSize(1)
+        assertThat(latest!![0].isExclusivelyNonTerrestrial).isFalse()
+    }
+
+    @Test
+    fun testSubscriptions_carrierMergedOnly_listHasCarrierMerged() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        setWifiState(isCarrierMerged = true)
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_CM)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        assertThat(latest).isEqualTo(listOf(MODEL_CM))
+    }
+
+    @Test
+    fun testSubscriptions_carrierMergedAndOther_listHasBothWithCarrierMergedLast() = runTest {
+        val latest by underTest.subscriptions.collectLastValue()
+
+        setWifiState(isCarrierMerged = true)
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1, SUB_2, SUB_CM)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2, MODEL_CM))
+    }
+
+    @Test
+    fun testActiveDataSubscriptionId_initialValueIsNull() = runTest {
+        assertThat(underTest.activeMobileDataSubscriptionId.collectLastValue().value)
+            .isEqualTo(null)
+    }
+
+    @Test
+    fun testActiveDataSubscriptionId_updates() = runTest {
+        val active by underTest.activeMobileDataSubscriptionId.collectLastValue()
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+        assertThat(active).isEqualTo(SUB_2_ID)
+    }
+
+    @Test
+    fun activeSubId_nullIfInvalidSubIdIsReceived() = runTest {
+        val latest by underTest.activeMobileDataSubscriptionId.collectLastValue()
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+        assertThat(latest).isNotNull()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
+
+        assertThat(latest).isNull()
+    }
+
+    @Test
+    fun activeRepo_initiallyNull() = runTest {
+        assertThat(underTest.activeMobileDataRepository.collectLastValue().value).isNull()
+    }
+
+    @Test
+    fun activeRepo_updatesWithActiveDataId() = runTest {
+        val latest by underTest.activeMobileDataRepository.collectLastValue()
+        testScope.runCurrent()
+
+        // GIVEN the subscription list is then updated which includes the active data sub id
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_2)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+        assertThat(latest?.subId).isEqualTo(SUB_2_ID)
+    }
+
+    @Test
+    fun activeRepo_nullIfActiveDataSubIdBecomesInvalid() = runTest {
+        val latest by underTest.activeMobileDataRepository.collectLastValue()
+        testScope.runCurrent()
+
+        // GIVEN the subscription list is then updated which includes the active data sub id
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_2)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+        testScope.runCurrent()
+
+        assertThat(latest).isNotNull()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
+        testScope.runCurrent()
+
+        assertThat(latest).isNull()
+    }
+
+    @Test
+    /** Regression test for b/268146648. */
+    fun activeSubIdIsSetBeforeSubscriptionsAreUpdated_doesNotThrow() = runTest {
+        val activeRepo by underTest.activeMobileDataRepository.collectLastValue()
+        val subscriptions by underTest.subscriptions.collectLastValue()
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+        testScope.runCurrent()
+
+        assertThat(subscriptions).isEmpty()
+        assertThat(activeRepo).isNull()
+    }
+
+    @Test
+    fun getRepoForSubId_activeDataSubIdIsRequestedBeforeSubscriptionsUpdate() = runTest {
+        underTest
+
+        var latestActiveRepo: MobileConnectionRepositoryKairos? = null
+        testScope.backgroundScope.launch {
+            kairos.activateSpec {
+                underTest.activeMobileDataSubscriptionId
+                    .combine(underTest.mobileConnectionsBySubId) { id, conns ->
+                        id?.let { conns[id] }
+                    }
+                    .observe {
+                        if (it != null) {
+                            latestActiveRepo = it
+                        }
+                    }
             }
         }
 
-        whenever(logBufferFactory.getOrCreate(anyString(), anyInt())).thenAnswer { _ ->
-            logcatTableLogBuffer(kosmos, "test")
+        val latestSubscriptions by underTest.subscriptions.collectLastValue()
+        testScope.runCurrent()
+
+        // Active data subscription id is sent, but no subscription change has been posted yet
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+        testScope.runCurrent()
+
+        // Subscriptions list is empty
+        assertThat(latestSubscriptions).isEmpty()
+
+        // getRepoForSubId does not throw
+        assertThat(latestActiveRepo).isNull()
+    }
+
+    @Test
+    fun activeDataSentBeforeSubscriptionList_subscriptionReusesActiveDataRepo() = runTest {
+        val activeRepo by underTest.activeMobileDataRepository.collectLastValue()
+        testScope.runCurrent()
+
+        // GIVEN active repo is updated before the subscription list updates
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+        testScope.runCurrent()
+
+        assertThat(activeRepo).isNull()
+
+        // GIVEN the subscription list is then updated which includes the active data sub id
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_2)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+        testScope.runCurrent()
+
+        // WHEN requesting a connection repository for the subscription
+        val newRepo =
+            kairos.transact { underTest.mobileConnectionsBySubId.map { it[SUB_2_ID] }.sample() }
+
+        // THEN the newly request repo has been cached and reused
+        assertThat(activeRepo).isSameInstanceAs(newRepo)
+    }
+
+    @Test
+    fun testConnectionRepository_validSubId_isCached() = runTest {
+        underTest
+
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        val repo1 by underTest.mobileConnectionsBySubId.map { it[SUB_1_ID] }.collectLastValue()
+        val repo2 by underTest.mobileConnectionsBySubId.map { it[SUB_1_ID] }.collectLastValue()
+
+        assertThat(repo1).isNotNull()
+        assertThat(repo1).isSameInstanceAs(repo2)
+    }
+
+    @Test
+    fun testConnectionRepository_carrierMergedSubId_isCached() = runTest {
+        underTest
+
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_CM)
+        setWifiState(isCarrierMerged = true)
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_CM)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        val repo1 by underTest.mobileConnectionsBySubId.map { it[SUB_CM_ID] }.collectLastValue()
+        val repo2 by underTest.mobileConnectionsBySubId.map { it[SUB_CM_ID] }.collectLastValue()
+
+        assertThat(repo1).isNotNull()
+        assertThat(repo1).isSameInstanceAs(repo2)
+    }
+
+    @SuppressLint("UnspecifiedRegisterReceiverFlag")
+    @Test
+    fun testDeviceEmergencyCallState_eagerlyChecksState() = runTest {
+        val latest by underTest.isDeviceEmergencyCallCapable.collectLastValue()
+
+        // Value starts out false
+        assertThat(latest).isFalse()
+        telephonyManager.stub { on { activeModemCount } doReturn 1 }
+        whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { _ ->
+            ServiceState().apply { isEmergencyOnly = true }
         }
 
-        whenever(
-                wifiPickerTrackerFactory.create(
-                    any(),
-                    any(),
-                    capture(wifiPickerTrackerCallback),
-                    any(),
-                )
-            )
-            .thenReturn(wifiPickerTracker)
+        // WHEN an appropriate intent gets sent out
+        val intent = serviceStateIntent(subId = -1)
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(applicationContext, intent)
+        testScope.runCurrent()
 
-        // For convenience, set up the subscription info callbacks
-        whenever(subscriptionManager.getActiveSubscriptionInfo(anyInt())).thenAnswer { invocation ->
+        // THEN the repo's state is updated despite no listeners
+        assertThat(latest).isEqualTo(true)
+    }
+
+    @Test
+    fun testDeviceEmergencyCallState_aggregatesAcrossSlots_oneTrue() = runTest {
+        val latest by underTest.isDeviceEmergencyCallCapable.collectLastValue()
+
+        // GIVEN there are multiple slots
+        telephonyManager.stub { on { activeModemCount } doReturn 4 }
+        // GIVEN only one of them reports ECM
+        whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { invocation ->
             when (invocation.getArgument(0) as Int) {
-                1 -> SUB_1
-                2 -> SUB_2
-                3 -> SUB_3
-                4 -> SUB_4
+                0 -> ServiceState().apply { isEmergencyOnly = false }
+                1 -> ServiceState().apply { isEmergencyOnly = false }
+                2 -> ServiceState().apply { isEmergencyOnly = true }
+                3 -> ServiceState().apply { isEmergencyOnly = false }
                 else -> null
             }
         }
 
-        connectivityRepository =
-            ConnectivityRepositoryImpl(
-                connectivityManager,
-                ConnectivitySlots(context),
-                context,
-                mock(),
-                mock(),
-                testScope.backgroundScope,
-                mock(),
-            )
-
-        airplaneModeRepository = FakeAirplaneModeRepository()
-
-        wifiRepository =
-            WifiRepositoryImpl(
-                mContext,
-                userRepository,
-                testScope.backgroundScope,
-                mainExecutor,
-                testDispatcher,
-                wifiPickerTrackerFactory,
-                wifiManager,
-                wifiLogBuffer,
-                wifiTableLogBuffer,
-            )
-
-        carrierConfigRepository = kosmos.carrierConfigRepository
-
-        connectionFactory =
-            MobileConnectionRepositoryImpl.Factory(
-                context,
-                fakeBroadcastDispatcher,
-                connectivityManager,
-                telephonyManager = telephonyManager,
-                bgDispatcher = testDispatcher,
-                logger = logger,
-                mobileMappingsProxy = mobileMappings,
-                scope = testScope.backgroundScope,
-                flags = flags,
-                carrierConfigRepository = carrierConfigRepository,
-            )
-        carrierMergedFactory =
-            CarrierMergedConnectionRepository.Factory(
-                telephonyManager,
-                testScope.backgroundScope.coroutineContext,
-                testScope.backgroundScope,
-                wifiRepository,
-            )
-        fullConnectionFactory =
-            FullMobileConnectionRepository.Factory(
-                scope = testScope.backgroundScope,
-                logFactory = logBufferFactory,
-                mobileRepoFactory = connectionFactory,
-                carrierMergedRepoFactory = carrierMergedFactory,
-            )
-
-        underTest =
-            MobileConnectionsRepositoryKairosImpl(
-                connectivityRepository,
-                subscriptionManager,
-                subscriptionManagerProxy,
-                telephonyManager,
-                logger,
-                summaryLogger,
-                mobileMappings,
-                fakeBroadcastDispatcher,
-                context,
-                /* bgDispatcher = */ testDispatcher,
-                testScope.backgroundScope,
-                /* mainDispatcher = */ testDispatcher,
-                airplaneModeRepository,
-                wifiRepository,
-                fullConnectionFactory,
-                updateMonitor,
-                mock(),
-            )
-
+        // GIVEN a broadcast goes out for the appropriate subID
+        val intent = serviceStateIntent(subId = -1)
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(applicationContext, intent)
         testScope.runCurrent()
+
+        // THEN the device is in ECM, because one of the service states is
+        assertThat(latest).isTrue()
     }
 
     @Test
-    fun testSubscriptions_initiallyEmpty() =
-        testScope.runTest {
-            assertThat(underTest.subscriptions.value).isEqualTo(listOf<SubscriptionModel>())
+    fun testDeviceEmergencyCallState_aggregatesAcrossSlots_allFalse() = runTest {
+        val latest by underTest.isDeviceEmergencyCallCapable.collectLastValue()
+
+        // GIVEN there are multiple slots
+        telephonyManager.stub { on { activeModemCount } doReturn 4 }
+        // GIVEN only one of them reports ECM
+        whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { invocation ->
+            when (invocation.getArgument(0) as Int) {
+                0 -> ServiceState().apply { isEmergencyOnly = false }
+                1 -> ServiceState().apply { isEmergencyOnly = false }
+                2 -> ServiceState().apply { isEmergencyOnly = false }
+                3 -> ServiceState().apply { isEmergencyOnly = false }
+                else -> null
+            }
         }
 
-    @Test
-    fun testSubscriptions_listUpdates() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.subscriptions)
+        // GIVEN a broadcast goes out for the appropriate subID
+        val intent = serviceStateIntent(subId = -1)
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(applicationContext, intent)
+        testScope.runCurrent()
 
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
-        }
-
-    @Test
-    fun testSubscriptions_removingSub_updatesList() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.subscriptions)
-
-            // WHEN 2 networks show up
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // WHEN one network is removed
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // THEN the subscriptions list represents the newest change
-            assertThat(latest).isEqualTo(listOf(MODEL_2))
-        }
-
-    @Test
-    fun subscriptions_subIsOnlyNtn_modelHasExclusivelyNtnTrue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.subscriptions)
-
-            val onlyNtnSub =
-                mock<SubscriptionInfo>().also {
-                    whenever(it.isOnlyNonTerrestrialNetwork).thenReturn(true)
-                    whenever(it.subscriptionId).thenReturn(45)
-                    whenever(it.groupUuid).thenReturn(GROUP_1)
-                    whenever(it.carrierName).thenReturn("NTN only")
-                    whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET)
-                }
-
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(onlyNtnSub))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].isExclusivelyNonTerrestrial).isTrue()
-        }
-
-    @Test
-    fun subscriptions_subIsNotOnlyNtn_modelHasExclusivelyNtnFalse() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.subscriptions)
-
-            val notOnlyNtnSub =
-                mock<SubscriptionInfo>().also {
-                    whenever(it.isOnlyNonTerrestrialNetwork).thenReturn(false)
-                    whenever(it.subscriptionId).thenReturn(45)
-                    whenever(it.groupUuid).thenReturn(GROUP_1)
-                    whenever(it.carrierName).thenReturn("NTN only")
-                    whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET)
-                }
-
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(notOnlyNtnSub))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(latest).hasSize(1)
-            assertThat(latest!![0].isExclusivelyNonTerrestrial).isFalse()
-        }
-
-    @Test
-    fun testSubscriptions_carrierMergedOnly_listHasCarrierMerged() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.subscriptions)
-
-            setWifiState(isCarrierMerged = true)
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_CM))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(latest).isEqualTo(listOf(MODEL_CM))
-        }
-
-    @Test
-    fun testSubscriptions_carrierMergedAndOther_listHasBothWithCarrierMergedLast() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.subscriptions)
-
-            setWifiState(isCarrierMerged = true)
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2, SUB_CM))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2, MODEL_CM))
-        }
-
-    @Test
-    fun testActiveDataSubscriptionId_initialValueIsNull() =
-        testScope.runTest {
-            assertThat(underTest.activeMobileDataSubscriptionId.value).isEqualTo(null)
-        }
-
-    @Test
-    fun testActiveDataSubscriptionId_updates() =
-        testScope.runTest {
-            val active by collectLastValue(underTest.activeMobileDataSubscriptionId)
-
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
-
-            assertThat(active).isEqualTo(SUB_2_ID)
-        }
-
-    @Test
-    fun activeSubId_nullIfInvalidSubIdIsReceived() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.activeMobileDataSubscriptionId)
-
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
-
-            assertThat(latest).isNotNull()
-
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
-
-            assertThat(latest).isNull()
-        }
-
-    @Test
-    fun activeRepo_initiallyNull() {
-        assertThat(underTest.activeMobileDataRepository.value).isNull()
+        // THEN the device is in ECM, because one of the service states is
+        assertThat(latest).isFalse()
     }
 
     @Test
-    fun activeRepo_updatesWithActiveDataId() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.activeMobileDataRepository)
+    fun testConnectionCache_clearsInvalidSubscriptions() = runTest {
+        underTest
 
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
-
-            assertThat(latest?.subId).isEqualTo(SUB_2_ID)
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1, SUB_2)
         }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        val repoCache by underTest.mobileConnectionsBySubId.collectLastValue()
+
+        assertThat(repoCache?.keys).containsExactly(SUB_1_ID, SUB_2_ID)
+
+        // SUB_2 disappears
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1)
+        }
+        getSubscriptionCallback().onSubscriptionsChanged()
+
+        assertThat(repoCache?.keys).containsExactly(SUB_1_ID)
+    }
 
     @Test
-    fun activeRepo_nullIfActiveDataSubIdBecomesInvalid() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.activeMobileDataRepository)
+    fun testConnectionCache_clearsInvalidSubscriptions_includingCarrierMerged() = runTest {
+        underTest
 
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
-
-            assertThat(latest).isNotNull()
-
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
-
-            assertThat(latest).isNull()
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_CM)
+        setWifiState(isCarrierMerged = true)
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1, SUB_2, SUB_CM)
         }
+        getSubscriptionCallback().onSubscriptionsChanged()
 
-    @Test
-    /** Regression test for b/268146648. */
-    fun activeSubIdIsSetBeforeSubscriptionsAreUpdated_doesNotThrow() =
-        testScope.runTest {
-            val activeRepo by collectLastValue(underTest.activeMobileDataRepository)
-            val subscriptions by collectLastValue(underTest.subscriptions)
+        val repoCache by underTest.mobileConnectionsBySubId.collectLastValue()
 
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+        assertThat(repoCache?.keys).containsExactly(SUB_1_ID, SUB_2_ID, SUB_CM_ID)
 
-            assertThat(subscriptions).isEmpty()
-            assertThat(activeRepo).isNotNull()
+        // SUB_2 and SUB_CM disappear
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1)
         }
+        getSubscriptionCallback().onSubscriptionsChanged()
 
-    @Test
-    fun getRepoForSubId_activeDataSubIdIsRequestedBeforeSubscriptionsUpdate() =
-        testScope.runTest {
-            var latestActiveRepo: MobileConnectionRepository? = null
-            collectLastValue(
-                underTest.activeMobileDataSubscriptionId.filterNotNull().onEach {
-                    latestActiveRepo = underTest.getRepoForSubId(it)
-                }
-            )
-
-            val latestSubscriptions by collectLastValue(underTest.subscriptions)
-
-            // Active data subscription id is sent, but no subscription change has been posted yet
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
-
-            // Subscriptions list is empty
-            assertThat(latestSubscriptions).isEmpty()
-            // getRepoForSubId does not throw
-            assertThat(latestActiveRepo).isNotNull()
-        }
-
-    @Test
-    fun activeDataSentBeforeSubscriptionList_subscriptionReusesActiveDataRepo() =
-        testScope.runTest {
-            val activeRepo by collectLastValue(underTest.activeMobileDataRepository)
-            collectLastValue(underTest.subscriptions)
-
-            // GIVEN active repo is updated before the subscription list updates
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
-
-            assertThat(activeRepo).isNotNull()
-
-            // GIVEN the subscription list is then updated which includes the active data sub id
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // WHEN requesting a connection repository for the subscription
-            val newRepo = underTest.getRepoForSubId(SUB_2_ID)
-
-            // THEN the newly request repo has been cached and reused
-            assertThat(activeRepo).isSameInstanceAs(newRepo)
-        }
-
-    @Test
-    fun testConnectionRepository_validSubId_isCached() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            val repo1 = underTest.getRepoForSubId(SUB_1_ID)
-            val repo2 = underTest.getRepoForSubId(SUB_1_ID)
-
-            assertThat(repo1).isSameInstanceAs(repo2)
-        }
-
-    @Test
-    fun testConnectionRepository_carrierMergedSubId_isCached() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_CM)
-            setWifiState(isCarrierMerged = true)
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_CM))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            val repo1 = underTest.getRepoForSubId(SUB_CM_ID)
-            val repo2 = underTest.getRepoForSubId(SUB_CM_ID)
-
-            assertThat(repo1).isSameInstanceAs(repo2)
-        }
-
-    @Test
-    fun testConnectionRepository_carrierMergedAndMobileSubs_usesCorrectRepos() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_CM)
-            setWifiState(isCarrierMerged = true)
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_CM))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            val carrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
-            val mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
-            assertThat(carrierMergedRepo.getIsCarrierMerged()).isTrue()
-            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
-        }
-
-    @Test
-    fun testSubscriptions_subNoLongerCarrierMerged_repoUpdates() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_CM)
-            setWifiState(isCarrierMerged = true)
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_CM))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            val carrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
-            var mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
-            assertThat(carrierMergedRepo.getIsCarrierMerged()).isTrue()
-            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
-
-            // WHEN the wifi network updates to be not carrier merged
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_ACTIVE)
-            setWifiState(isCarrierMerged = false)
-            runCurrent()
-
-            // THEN the repos update
-            val noLongerCarrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
-            mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
-            assertThat(noLongerCarrierMergedRepo.getIsCarrierMerged()).isFalse()
-            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
-        }
-
-    @Test
-    fun testSubscriptions_subBecomesCarrierMerged_repoUpdates() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_ACTIVE)
-            setWifiState(isCarrierMerged = false)
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_CM))
-            getSubscriptionCallback().onSubscriptionsChanged()
-            runCurrent()
-
-            val notYetCarrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
-            var mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
-            assertThat(notYetCarrierMergedRepo.getIsCarrierMerged()).isFalse()
-            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
-
-            // WHEN the wifi network updates to be carrier merged
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_CM)
-            setWifiState(isCarrierMerged = true)
-            runCurrent()
-
-            // THEN the repos update
-            val carrierMergedRepo = underTest.getRepoForSubId(SUB_CM_ID)
-            mobileRepo = underTest.getRepoForSubId(SUB_1_ID)
-            assertThat(carrierMergedRepo.getIsCarrierMerged()).isTrue()
-            assertThat(mobileRepo.getIsCarrierMerged()).isFalse()
-        }
-
-    @SuppressLint("UnspecifiedRegisterReceiverFlag")
-    @Test
-    fun testDeviceEmergencyCallState_eagerlyChecksState() =
-        testScope.runTest {
-            // Value starts out false
-            assertThat(underTest.isDeviceEmergencyCallCapable.value).isFalse()
-            whenever(telephonyManager.activeModemCount).thenReturn(1)
-            whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { _ ->
-                ServiceState().apply { isEmergencyOnly = true }
-            }
-
-            // WHEN an appropriate intent gets sent out
-            val intent = serviceStateIntent(subId = -1)
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
-            runCurrent()
-
-            // THEN the repo's state is updated despite no listeners
-            assertThat(underTest.isDeviceEmergencyCallCapable.value).isEqualTo(true)
-        }
-
-    @Test
-    fun testDeviceEmergencyCallState_aggregatesAcrossSlots_oneTrue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.isDeviceEmergencyCallCapable)
-
-            // GIVEN there are multiple slots
-            whenever(telephonyManager.activeModemCount).thenReturn(4)
-            // GIVEN only one of them reports ECM
-            whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { invocation ->
-                when (invocation.getArgument(0) as Int) {
-                    0 -> ServiceState().apply { isEmergencyOnly = false }
-                    1 -> ServiceState().apply { isEmergencyOnly = false }
-                    2 -> ServiceState().apply { isEmergencyOnly = true }
-                    3 -> ServiceState().apply { isEmergencyOnly = false }
-                    else -> null
-                }
-            }
-
-            // GIVEN a broadcast goes out for the appropriate subID
-            val intent = serviceStateIntent(subId = -1)
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
-            runCurrent()
-
-            // THEN the device is in ECM, because one of the service states is
-            assertThat(latest).isTrue()
-        }
-
-    @Test
-    fun testDeviceEmergencyCallState_aggregatesAcrossSlots_allFalse() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.isDeviceEmergencyCallCapable)
-
-            // GIVEN there are multiple slots
-            whenever(telephonyManager.activeModemCount).thenReturn(4)
-            // GIVEN only one of them reports ECM
-            whenever(telephonyManager.getServiceStateForSlot(any())).thenAnswer { invocation ->
-                when (invocation.getArgument(0) as Int) {
-                    0 -> ServiceState().apply { isEmergencyOnly = false }
-                    1 -> ServiceState().apply { isEmergencyOnly = false }
-                    2 -> ServiceState().apply { isEmergencyOnly = false }
-                    3 -> ServiceState().apply { isEmergencyOnly = false }
-                    else -> null
-                }
-            }
-
-            // GIVEN a broadcast goes out for the appropriate subID
-            val intent = serviceStateIntent(subId = -1)
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
-            runCurrent()
-
-            // THEN the device is in ECM, because one of the service states is
-            assertThat(latest).isFalse()
-        }
-
-    @Test
-    @Ignore("b/333912012")
-    fun testConnectionCache_clearsInvalidSubscriptions() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // Get repos to trigger caching
-            val repo1 = underTest.getRepoForSubId(SUB_1_ID)
-            val repo2 = underTest.getRepoForSubId(SUB_2_ID)
-
-            assertThat(underTest.getSubIdRepoCache())
-                .containsExactly(SUB_1_ID, repo1, SUB_2_ID, repo2)
-
-            // SUB_2 disappears
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(underTest.getSubIdRepoCache()).containsExactly(SUB_1_ID, repo1)
-        }
-
-    @Test
-    @Ignore("b/333912012")
-    fun testConnectionCache_clearsInvalidSubscriptions_includingCarrierMerged() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, WIFI_NETWORK_CAPS_CM)
-            setWifiState(isCarrierMerged = true)
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2, SUB_CM))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // Get repos to trigger caching
-            val repo1 = underTest.getRepoForSubId(SUB_1_ID)
-            val repo2 = underTest.getRepoForSubId(SUB_2_ID)
-            val repoCarrierMerged = underTest.getRepoForSubId(SUB_CM_ID)
-
-            assertThat(underTest.getSubIdRepoCache())
-                .containsExactly(SUB_1_ID, repo1, SUB_2_ID, repo2, SUB_CM_ID, repoCarrierMerged)
-
-            // SUB_2 and SUB_CM disappear
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(underTest.getSubIdRepoCache()).containsExactly(SUB_1_ID, repo1)
-        }
+        assertThat(repoCache?.keys).containsExactly(SUB_1_ID)
+    }
 
     /** Regression test for b/261706421 */
     @Test
-    @Ignore("b/333912012")
-    fun testConnectionsCache_clearMultipleSubscriptionsAtOnce_doesNotThrow() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
+    fun testConnectionsCache_clearMultipleSubscriptionsAtOnce_doesNotThrow() = runTest {
+        underTest
 
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // Get repos to trigger caching
-            val repo1 = underTest.getRepoForSubId(SUB_1_ID)
-            val repo2 = underTest.getRepoForSubId(SUB_2_ID)
-
-            assertThat(underTest.getSubIdRepoCache())
-                .containsExactly(SUB_1_ID, repo1, SUB_2_ID, repo2)
-
-            // All subscriptions disappear
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList).thenReturn(listOf())
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            assertThat(underTest.getSubIdRepoCache()).isEmpty()
+        subscriptionManager.stub {
+            on { completeActiveSubscriptionInfoList } doReturn listOf(SUB_1, SUB_2)
         }
+        getSubscriptionCallback().onSubscriptionsChanged()
 
-    @Test
-    fun testConnectionsCache_keepsReposCached() =
-        testScope.runTest {
-            // Collect subscriptions to start the job
-            collectLastValue(underTest.subscriptions)
+        val repoCache by underTest.mobileConnectionsBySubId.collectLastValue()
 
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1))
-            getSubscriptionCallback().onSubscriptionsChanged()
+        assertThat(repoCache?.keys).containsExactly(SUB_1_ID, SUB_2_ID)
 
-            val repo1_1 = underTest.getRepoForSubId(SUB_1_ID)
+        // All subscriptions disappear
+        subscriptionManager.stub { on { completeActiveSubscriptionInfoList } doReturn listOf() }
+        getSubscriptionCallback().onSubscriptionsChanged()
 
-            // All subscriptions disappear
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList).thenReturn(listOf())
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // Sub1 comes back
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            val repo1_2 = underTest.getRepoForSubId(SUB_1_ID)
-
-            assertThat(repo1_1).isSameInstanceAs(repo1_2)
-        }
-
-    @Test
-    fun testConnectionsCache_doesNotDropReferencesThatHaveBeenRealized() =
-        testScope.runTest {
-            // Collect subscriptions to start the job
-            collectLastValue(underTest.subscriptions)
-
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // Client grabs a reference to a repository, but doesn't keep it around
-            underTest.getRepoForSubId(SUB_1_ID)
-
-            // All subscriptions disappear
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList).thenReturn(listOf())
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            val repo1 = underTest.getRepoForSubId(SUB_1_ID)
-
-            assertThat(repo1).isNotNull()
-        }
-
-    @Test
-    fun testConnectionRepository_invalidSubId_doesNotThrow() =
-        testScope.runTest {
-            underTest.getRepoForSubId(SUB_1_ID)
-            // No exception
-        }
-
-    @Test
-    fun connectionRepository_logBufferContainsSubIdInItsName() =
-        testScope.runTest {
-            collectLastValue(underTest.subscriptions)
-
-            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
-                .thenReturn(listOf(SUB_1, SUB_2))
-            getSubscriptionCallback().onSubscriptionsChanged()
-
-            // Get repos to trigger creation
-            underTest.getRepoForSubId(SUB_1_ID)
-            verify(logBufferFactory).getOrCreate(eq(tableBufferLogName(SUB_1_ID)), anyInt())
-            underTest.getRepoForSubId(SUB_2_ID)
-            verify(logBufferFactory).getOrCreate(eq(tableBufferLogName(SUB_2_ID)), anyInt())
-        }
-
-    @Test
-    fun testDefaultDataSubId_updatesOnBroadcast() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.defaultDataSubId)
-
-            assertThat(latest).isEqualTo(null)
-
-            val intent2 =
-                Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
-                    .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_2_ID)
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent2)
-
-            assertThat(latest).isEqualTo(SUB_2_ID)
-
-            val intent1 =
-                Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
-                    .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent1)
-
-            assertThat(latest).isEqualTo(SUB_1_ID)
-        }
-
-    @Test
-    fun defaultDataSubId_fetchesInitialValueOnStart() =
-        testScope.runTest {
-            subscriptionManagerProxy.defaultDataSubId = 2
-            val latest by collectLastValue(underTest.defaultDataSubId)
-
-            assertThat(latest).isEqualTo(2)
-        }
-
-    @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
-            var latest: Int? = null
-            var job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this)
-            runCurrent()
-
-            assertThat(latest).isEqualTo(2)
-
-            job.cancel()
-
-            // Collectors go away but come back later
-
-            latest = null
-
-            subscriptionManagerProxy.defaultDataSubId = 1
-
-            job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this)
-            runCurrent()
-
-            assertThat(latest).isEqualTo(1)
-
-            job.cancel()
-        }
-
-    @Test
-    fun mobileIsDefault_startsAsFalse() {
-        assertThat(underTest.mobileIsDefault.value).isFalse()
+        assertThat(repoCache).isEmpty()
     }
 
     @Test
-    fun mobileIsDefault_capsHaveCellular_isDefault() =
-        testScope.runTest {
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                }
+    fun testDefaultDataSubId_updatesOnBroadcast() = runTest {
+        val latest by underTest.defaultDataSubId.collectLastValue()
 
-            val latest by collectLastValue(underTest.mobileIsDefault)
+        assertThat(latest).isEqualTo(null)
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        val intent2 =
+            Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+                .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_2_ID)
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(applicationContext, intent2)
 
-            assertThat(latest).isTrue()
-        }
+        assertThat(latest).isEqualTo(SUB_2_ID)
+
+        val intent1 =
+            Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+                .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(applicationContext, intent1)
+
+        assertThat(latest).isEqualTo(SUB_1_ID)
+    }
 
     @Test
-    fun mobileIsDefault_capsDoNotHaveCellular_isNotDefault() =
-        testScope.runTest {
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(false)
-                }
+    fun defaultDataSubId_fetchesInitialValueOnStart() = runTest {
+        subscriptionManagerProxy.fake.defaultDataSubId = 2
+        val latest by underTest.defaultDataSubId.collectLastValue()
 
-            val latest by collectLastValue(underTest.mobileIsDefault)
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
-
-            assertThat(latest).isFalse()
-        }
+        assertThat(latest).isEqualTo(2)
+    }
 
     @Test
-    fun mobileIsDefault_carrierMergedViaMobile_isDefault() =
-        testScope.runTest {
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply { whenever(this.isCarrierMerged).thenReturn(true) }
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(carrierMergedInfo)
-                }
-
-            val latest by collectLastValue(underTest.mobileIsDefault)
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
-
-            assertThat(latest).isTrue()
-        }
+    fun mobileIsDefault_startsAsFalse() = runTest {
+        assertThat(underTest.mobileIsDefault.collectLastValue().value).isFalse()
+    }
 
     @Test
-    fun mobileIsDefault_wifiDefault_mobileNotDefault() =
-        testScope.runTest {
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                }
+    fun mobileIsDefault_capsHaveCellular_isDefault() = runTest {
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+            }
 
-            val latest by collectLastValue(underTest.mobileIsDefault)
+        val latest by underTest.mobileIsDefault.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
 
-            assertThat(latest).isFalse()
-        }
+        assertThat(latest).isTrue()
+    }
 
     @Test
-    fun mobileIsDefault_ethernetDefault_mobileNotDefault() =
-        testScope.runTest {
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_ETHERNET)).thenReturn(true)
-                }
+    fun mobileIsDefault_capsDoNotHaveCellular_isNotDefault() = runTest {
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn false
+            }
 
-            val latest by collectLastValue(underTest.mobileIsDefault)
+        val latest by underTest.mobileIsDefault.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
 
-            assertThat(latest).isFalse()
-        }
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun mobileIsDefault_carrierMergedViaMobile_isDefault() = runTest {
+        val carrierMergedInfo = mock<WifiInfo> { on { isCarrierMerged } doReturn true }
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                on { transportInfo } doReturn carrierMergedInfo
+            }
+
+        val latest by underTest.mobileIsDefault.collectLastValue()
+
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+
+        assertThat(latest).isTrue()
+    }
+
+    @Test
+    fun mobileIsDefault_wifiDefault_mobileNotDefault() = runTest {
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_WIFI) } doReturn true
+            }
+
+        val latest by underTest.mobileIsDefault.collectLastValue()
+
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+
+        assertThat(latest).isFalse()
+    }
+
+    @Test
+    fun mobileIsDefault_ethernetDefault_mobileNotDefault() = runTest {
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_ETHERNET) } doReturn true
+            }
+
+        val latest by underTest.mobileIsDefault.collectLastValue()
+
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+
+        assertThat(latest).isFalse()
+    }
 
     /** Regression test for b/272586234. */
     @Test
-    fun hasCarrierMergedConnection_carrierMergedViaWifi_isTrue() =
-        testScope.runTest {
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply {
-                    whenever(this.isCarrierMerged).thenReturn(true)
-                    whenever(this.isPrimary).thenReturn(true)
-                }
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(carrierMergedInfo)
-                }
+    fun hasCarrierMergedConnection_carrierMergedViaWifi_isTrue() = runTest {
+        val carrierMergedInfo =
+            mock<WifiInfo> {
+                on { isCarrierMerged } doReturn true
+                on { isPrimary } doReturn true
+            }
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_WIFI) } doReturn true
+                on { transportInfo } doReturn carrierMergedInfo
+            }
 
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+        val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
-            setWifiState(isCarrierMerged = true)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        setWifiState(isCarrierMerged = true)
 
-            assertThat(latest).isTrue()
-        }
+        assertThat(latest).isTrue()
+    }
 
     @Test
-    fun hasCarrierMergedConnection_carrierMergedViaMobile_isTrue() =
-        testScope.runTest {
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply {
-                    whenever(this.isCarrierMerged).thenReturn(true)
-                    whenever(this.isPrimary).thenReturn(true)
-                }
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(carrierMergedInfo)
-                }
+    fun hasCarrierMergedConnection_carrierMergedViaMobile_isTrue() = runTest {
+        val carrierMergedInfo =
+            mock<WifiInfo> {
+                on { isCarrierMerged } doReturn true
+                on { isPrimary } doReturn true
+            }
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                on { transportInfo } doReturn carrierMergedInfo
+            }
 
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+        val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
-            setWifiState(isCarrierMerged = true)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        setWifiState(isCarrierMerged = true)
 
-            assertThat(latest).isTrue()
-        }
+        assertThat(latest).isTrue()
+    }
 
-    private fun newWifiNetwork(wifiInfo: WifiInfo): Network {
+    private fun KairosTestScope.newWifiNetwork(wifiInfo: WifiInfo): Network {
         val network = mock<Network>()
         val capabilities =
-            mock<NetworkCapabilities>().also {
-                whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                whenever(it.transportInfo).thenReturn(wifiInfo)
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_WIFI) } doReturn true
+                on { transportInfo } doReturn wifiInfo
             }
-        whenever(connectivityManager.getNetworkCapabilities(network)).thenReturn(capabilities)
-
+        connectivityManager.stub { on { getNetworkCapabilities(network) } doReturn capabilities }
         return network
     }
 
     /** Regression test for b/272586234. */
     @Test
-    fun hasCarrierMergedConnection_carrierMergedViaWifiWithVcnTransport_isTrue() =
-        testScope.runTest {
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply {
-                    whenever(this.isCarrierMerged).thenReturn(true)
-                    whenever(this.isPrimary).thenReturn(true)
-                }
-            val underlyingWifi = newWifiNetwork(carrierMergedInfo)
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(vcnTransportInfo)
-                    whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi))
-                }
+    fun hasCarrierMergedConnection_carrierMergedViaWifiWithVcnTransport_isTrue() = runTest {
+        val carrierMergedInfo =
+            mock<WifiInfo> {
+                on { isCarrierMerged } doReturn true
+                on { isPrimary } doReturn true
+            }
+        val underlyingWifi = newWifiNetwork(carrierMergedInfo)
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_WIFI) } doReturn true
+                on { transportInfo } doReturn vcnTransportInfo
+                on { underlyingNetworks } doReturn listOf(underlyingWifi)
+            }
 
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+        val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
-            setWifiState(isCarrierMerged = true)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        setWifiState(isCarrierMerged = true)
 
-            assertThat(latest).isTrue()
-        }
+        assertThat(latest).isTrue()
+    }
 
     @Test
-    fun hasCarrierMergedConnection_carrierMergedViaMobileWithVcnTransport_isTrue() =
-        testScope.runTest {
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply {
-                    whenever(this.isCarrierMerged).thenReturn(true)
-                    whenever(this.isPrimary).thenReturn(true)
-                }
-            val underlyingWifi = newWifiNetwork(carrierMergedInfo)
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(vcnTransportInfo)
-                    whenever(it.underlyingNetworks).thenReturn(listOf(underlyingWifi))
-                }
+    fun hasCarrierMergedConnection_carrierMergedViaMobileWithVcnTransport_isTrue() = runTest {
+        val carrierMergedInfo =
+            mock<WifiInfo> {
+                on { isCarrierMerged } doReturn true
+                on { isPrimary } doReturn true
+            }
+        val underlyingWifi = newWifiNetwork(carrierMergedInfo)
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                on { transportInfo } doReturn vcnTransportInfo
+                on { underlyingNetworks } doReturn listOf(underlyingWifi)
+            }
 
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+        val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
-            setWifiState(isCarrierMerged = true)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        setWifiState(isCarrierMerged = true)
 
-            assertThat(latest).isTrue()
-        }
+        assertThat(latest).isTrue()
+    }
 
     @Test
-    fun hasCarrierMergedConnection_isCarrierMergedViaUnderlyingWifi_isTrue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+    fun hasCarrierMergedConnection_isCarrierMergedViaUnderlyingWifi_isTrue() = runTest {
+        val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
-            val underlyingNetwork = mock<Network>()
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply {
-                    whenever(this.isCarrierMerged).thenReturn(true)
-                    whenever(this.isPrimary).thenReturn(true)
-                }
-            val underlyingWifiCapabilities =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(carrierMergedInfo)
-                }
-            whenever(connectivityManager.getNetworkCapabilities(underlyingNetwork))
-                .thenReturn(underlyingWifiCapabilities)
-
-            // WHEN the main capabilities have an underlying carrier merged network via WIFI
-            // transport and WifiInfo
-            val mainCapabilities =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(null)
-                    whenever(it.underlyingNetworks).thenReturn(listOf(underlyingNetwork))
-                }
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, mainCapabilities)
-            setWifiState(isCarrierMerged = true)
-
-            // THEN there's a carrier merged connection
-            assertThat(latest).isTrue()
+        val underlyingNetwork = mock<Network>()
+        val carrierMergedInfo =
+            mock<WifiInfo> {
+                on { isCarrierMerged } doReturn true
+                on { isPrimary } doReturn true
+            }
+        val underlyingWifiCapabilities =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_WIFI) } doReturn true
+                on { transportInfo } doReturn carrierMergedInfo
+            }
+        connectivityManager.stub {
+            on { getNetworkCapabilities(underlyingNetwork) } doReturn underlyingWifiCapabilities
         }
 
+        // WHEN the main capabilities have an underlying carrier merged network via WIFI
+        // transport and WifiInfo
+        val mainCapabilities =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                on { transportInfo } doReturn null
+                on { underlyingNetworks } doReturn listOf(underlyingNetwork)
+            }
+
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, mainCapabilities)
+        setWifiState(isCarrierMerged = true)
+
+        // THEN there's a carrier merged connection
+        assertThat(latest).isTrue()
+    }
+
     @Test
-    fun hasCarrierMergedConnection_isCarrierMergedViaUnderlyingCellular_isTrue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+    fun hasCarrierMergedConnection_isCarrierMergedViaUnderlyingCellular_isTrue() = runTest {
+        val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
-            val underlyingCarrierMergedNetwork = mock<Network>()
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply {
-                    whenever(this.isCarrierMerged).thenReturn(true)
-                    whenever(this.isPrimary).thenReturn(true)
-                }
+        val underlyingCarrierMergedNetwork = mock<Network>()
+        val carrierMergedInfo =
+            mock<WifiInfo> {
+                on { isCarrierMerged } doReturn true
+                on { isPrimary } doReturn true
+            }
 
-            // The Wifi network that is under the VCN network
-            val physicalWifiNetwork = newWifiNetwork(carrierMergedInfo)
+        // The Wifi network that is under the VCN network
+        val physicalWifiNetwork = newWifiNetwork(carrierMergedInfo)
 
-            val underlyingCapabilities =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(vcnTransportInfo)
-                    whenever(it.underlyingNetworks).thenReturn(listOf(physicalWifiNetwork))
-                }
-            whenever(connectivityManager.getNetworkCapabilities(underlyingCarrierMergedNetwork))
-                .thenReturn(underlyingCapabilities)
-
-            // WHEN the main capabilities have an underlying carrier merged network via CELLULAR
-            // transport and VcnTransportInfo
-            val mainCapabilities =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(null)
-                    whenever(it.underlyingNetworks)
-                        .thenReturn(listOf(underlyingCarrierMergedNetwork))
-                }
-
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, mainCapabilities)
-            setWifiState(isCarrierMerged = true)
-
-            // THEN there's a carrier merged connection
-            assertThat(latest).isTrue()
+        val underlyingCapabilities =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                on { transportInfo } doReturn vcnTransportInfo
+                on { underlyingNetworks } doReturn listOf(physicalWifiNetwork)
+            }
+        connectivityManager.stub {
+            on { getNetworkCapabilities(underlyingCarrierMergedNetwork) } doReturn
+                underlyingCapabilities
         }
 
+        // WHEN the main capabilities have an underlying carrier merged network via CELLULAR
+        // transport and VcnTransportInfo
+        val mainCapabilities =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                on { transportInfo } doReturn null
+                on { underlyingNetworks } doReturn listOf(underlyingCarrierMergedNetwork)
+            }
+
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, mainCapabilities)
+        setWifiState(isCarrierMerged = true)
+
+        // THEN there's a carrier merged connection
+        assertThat(latest).isTrue()
+    }
+
     /** Regression test for b/272586234. */
     @Test
     fun hasCarrierMergedConnection_defaultIsWifiNotCarrierMerged_wifiRepoIsCarrierMerged_isTrue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+        runTest {
+            val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
             // WHEN the default callback is TRANSPORT_WIFI but not carrier merged
-            val carrierMergedInfo =
-                mock<WifiInfo>().apply { whenever(this.isCarrierMerged).thenReturn(false) }
+            val carrierMergedInfo = mock<WifiInfo> { on { isCarrierMerged } doReturn false }
             val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(carrierMergedInfo)
+                Mockito.mock(NetworkCapabilities::class.java).stub {
+                    on { hasTransport(TRANSPORT_WIFI) } doReturn true
+                    on { transportInfo } doReturn carrierMergedInfo
                 }
             getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
 
@@ -1194,37 +937,36 @@
 
     /** Regression test for b/278618530. */
     @Test
-    fun hasCarrierMergedConnection_defaultIsCellular_wifiRepoIsCarrierMerged_isFalse() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+    fun hasCarrierMergedConnection_defaultIsCellular_wifiRepoIsCarrierMerged_isFalse() = runTest {
+        val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
-            // WHEN the default callback is TRANSPORT_CELLULAR and not carrier merged
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(null)
-                }
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        // WHEN the default callback is TRANSPORT_CELLULAR and not carrier merged
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                on { transportInfo } doReturn null
+            }
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
 
-            // BUT the wifi repo has gotten updates that it *is* carrier merged
-            setWifiState(isCarrierMerged = true)
+        // BUT the wifi repo has gotten updates that it *is* carrier merged
+        setWifiState(isCarrierMerged = true)
 
-            // THEN hasCarrierMergedConnection is **false** (The default network being CELLULAR
-            // takes precedence over the wifi network being carrier merged.)
-            assertThat(latest).isFalse()
-        }
+        // THEN hasCarrierMergedConnection is **false** (The default network being CELLULAR
+        // takes precedence over the wifi network being carrier merged.)
+        assertThat(latest).isFalse()
+    }
 
     /** Regression test for b/278618530. */
     @Test
     fun hasCarrierMergedConnection_defaultCellular_wifiIsCarrierMerged_airplaneMode_isTrue() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.hasCarrierMergedConnection)
+        runTest {
+            val latest by underTest.hasCarrierMergedConnection.collectLastValue()
 
             // WHEN the default callback is TRANSPORT_CELLULAR and not carrier merged
             val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
-                    whenever(it.transportInfo).thenReturn(null)
+                Mockito.mock(NetworkCapabilities::class.java).stub {
+                    on { hasTransport(TRANSPORT_CELLULAR) } doReturn true
+                    on { transportInfo } doReturn null
                 }
             getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
 
@@ -1238,269 +980,254 @@
         }
 
     @Test
-    fun defaultConnectionIsValidated_startsAsFalse() {
-        assertThat(underTest.defaultConnectionIsValidated.value).isFalse()
+    fun defaultConnectionIsValidated_startsAsFalse() = runTest {
+        assertThat(underTest.defaultConnectionIsValidated.collectLastValue().value).isFalse()
     }
 
     @Test
-    fun defaultConnectionIsValidated_capsHaveValidated_isValidated() =
-        testScope.runTest {
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(true)
-                }
+    fun defaultConnectionIsValidated_capsHaveValidated_isValidated() = runTest {
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasCapability(NET_CAPABILITY_VALIDATED) } doReturn true
+            }
 
-            val latest by collectLastValue(underTest.defaultConnectionIsValidated)
+        val latest by underTest.defaultConnectionIsValidated.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
 
-            assertThat(latest).isTrue()
-        }
+        assertThat(latest).isTrue()
+    }
 
     @Test
-    fun defaultConnectionIsValidated_capsHaveNotValidated_isNotValidated() =
-        testScope.runTest {
-            val caps =
-                mock<NetworkCapabilities>().also {
-                    whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(false)
-                }
+    fun defaultConnectionIsValidated_capsHaveNotValidated_isNotValidated() = runTest {
+        val caps =
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasCapability(NET_CAPABILITY_VALIDATED) } doReturn false
+            }
 
-            val latest by collectLastValue(underTest.defaultConnectionIsValidated)
+        val latest by underTest.defaultConnectionIsValidated.collectLastValue()
 
-            getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
+        getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, caps)
 
-            assertThat(latest).isFalse()
-        }
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun config_initiallyFromContext() =
-        testScope.runTest {
-            overrideResource(R.bool.config_showMin3G, true)
-            val configFromContext = MobileMappings.Config.readConfig(context)
-            assertThat(configFromContext.showAtLeast3G).isTrue()
+    fun config_initiallyFromContext() = runTest {
+        overrideResource(R.bool.config_showMin3G, true)
+        val configFromContext = MobileMappings.Config.readConfig(applicationContext)
+        assertThat(configFromContext.showAtLeast3G).isTrue()
 
-            // The initial value will be fetched when the repo is created, so we need to override
-            // the resources and then re-create the repo.
-            underTest =
-                MobileConnectionsRepositoryKairosImpl(
-                    connectivityRepository,
-                    subscriptionManager,
-                    subscriptionManagerProxy,
-                    telephonyManager,
-                    logger,
-                    summaryLogger,
-                    mobileMappings,
-                    fakeBroadcastDispatcher,
-                    context,
-                    testDispatcher,
-                    testScope.backgroundScope,
-                    testDispatcher,
-                    airplaneModeRepository,
-                    wifiRepository,
-                    fullConnectionFactory,
-                    updateMonitor,
-                    mock(),
-                )
+        val latest by underTest.defaultDataSubRatConfig.collectLastValue()
 
-            val latest by collectLastValue(underTest.defaultDataSubRatConfig)
-
-            assertTrue(latest!!.areEqual(configFromContext))
-            assertTrue(latest!!.showAtLeast3G)
-        }
+        assertTrue(latest!!.areEqual(configFromContext))
+        assertTrue(latest!!.showAtLeast3G)
+    }
 
     @Test
-    fun config_subIdChangeEvent_updated() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.defaultDataSubRatConfig)
+    fun config_subIdChangeEvent_updated() = runTest {
+        val latest by underTest.defaultDataSubRatConfig.collectLastValue()
 
-            assertThat(latest!!.showAtLeast3G).isFalse()
+        assertThat(latest!!.showAtLeast3G).isFalse()
 
-            overrideResource(R.bool.config_showMin3G, true)
-            val configFromContext = MobileMappings.Config.readConfig(context)
-            assertThat(configFromContext.showAtLeast3G).isTrue()
+        overrideResource(R.bool.config_showMin3G, true)
+        val configFromContext = MobileMappings.Config.readConfig(applicationContext)
+        assertThat(configFromContext.showAtLeast3G).isTrue()
 
-            // WHEN the change event is fired
-            val intent =
-                Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
-                    .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
+        // WHEN the change event is fired
+        val intent =
+            Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+                .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(applicationContext, intent)
 
-            // THEN the config is updated
-            assertTrue(latest!!.areEqual(configFromContext))
-            assertTrue(latest!!.showAtLeast3G)
-        }
+        // THEN the config is updated
+        assertThat(latest?.areEqual(configFromContext)).isEqualTo(true)
+        assertThat(latest?.showAtLeast3G).isEqualTo(true)
+    }
 
     @Test
-    fun config_carrierConfigChangeEvent_updated() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.defaultDataSubRatConfig)
+    fun config_carrierConfigChangeEvent_updated() = runTest {
+        val latest by underTest.defaultDataSubRatConfig.collectLastValue()
 
-            assertThat(latest!!.showAtLeast3G).isFalse()
+        assertThat(latest!!.showAtLeast3G).isFalse()
 
-            overrideResource(R.bool.config_showMin3G, true)
-            val configFromContext = MobileMappings.Config.readConfig(context)
-            assertThat(configFromContext.showAtLeast3G).isTrue()
+        overrideResource(R.bool.config_showMin3G, true)
+        val configFromContext = MobileMappings.Config.readConfig(applicationContext)
+        assertThat(configFromContext.showAtLeast3G).isTrue()
 
-            // WHEN the change event is fired
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
-                Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
-            )
+        // WHEN the change event is fired
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+            applicationContext,
+            Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
+        )
 
-            // THEN the config is updated
-            assertThat(latest!!.areEqual(configFromContext)).isTrue()
-            assertThat(latest!!.showAtLeast3G).isTrue()
-        }
+        // THEN the config is updated
+        assertThat(latest?.areEqual(configFromContext)).isEqualTo(true)
+        assertThat(latest?.showAtLeast3G).isEqualTo(true)
+    }
 
     @Test
-    fun carrierConfig_initialValueIsFetched() =
-        testScope.runTest {
-            // Value starts out false
-            assertThat(underTest.defaultDataSubRatConfig.value.showAtLeast3G).isFalse()
+    fun carrierConfig_initialValueIsFetched() = runTest {
+        underTest
+        testScope.runCurrent()
 
-            overrideResource(R.bool.config_showMin3G, true)
-            val configFromContext = MobileMappings.Config.readConfig(context)
-            assertThat(configFromContext.showAtLeast3G).isTrue()
+        // Value starts out false
+        assertThat(underTest.defaultDataSubRatConfig.sample().showAtLeast3G).isFalse()
 
-            // WHEN the change event is fired
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
-                Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
-            )
+        overrideResource(R.bool.config_showMin3G, true)
+        val configFromContext = MobileMappings.Config.readConfig(applicationContext)
+        assertThat(configFromContext.showAtLeast3G).isTrue()
 
-            // WHEN collection starts AFTER the broadcast is sent out
-            val latest by collectLastValue(underTest.defaultDataSubRatConfig)
+        assertThat(broadcastDispatcher.numReceiversRegistered).isAtLeast(1)
 
-            // THEN the config has the updated value
-            assertThat(latest!!.areEqual(configFromContext)).isTrue()
-            assertThat(latest!!.showAtLeast3G).isTrue()
-        }
+        // WHEN the change event is fired
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+            applicationContext,
+            Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
+        )
+        testScope.runCurrent()
+
+        // WHEN collection starts AFTER the broadcast is sent out
+        val latest by underTest.defaultDataSubRatConfig.collectLastValue()
+
+        // THEN the config has the updated value
+        assertWithMessage("showAtLeast3G is false").that(latest!!.showAtLeast3G).isTrue()
+        assertWithMessage("not equal").that(latest!!.areEqual(configFromContext)).isTrue()
+    }
 
     @Test
-    fun activeDataChange_inSameGroup_emitsUnit() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.activeSubChangedInGroupEvent)
-
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_3_ID_GROUPED)
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_4_ID_GROUPED)
-
-            assertThat(latest).isEqualTo(Unit)
+    fun activeDataChange_inSameGroup_emitsUnit() = runTest {
+        var eventCount = 0
+        underTest
+        testScope.backgroundScope.launch {
+            kairos.activateSpec { underTest.activeSubChangedInGroupEvent.observe { eventCount++ } }
         }
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_3_ID_GROUPED)
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_4_ID_GROUPED)
+        testScope.runCurrent()
+
+        assertThat(eventCount).isEqualTo(1)
+    }
 
     @Test
-    fun activeDataChange_notInSameGroup_doesNotEmit() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.activeSubChangedInGroupEvent)
-
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_3_ID_GROUPED)
-            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
-                .onActiveDataSubscriptionIdChanged(SUB_1_ID)
-
-            assertThat(latest).isEqualTo(null)
+    fun activeDataChange_notInSameGroup_doesNotEmit() = runTest {
+        var eventCount = 0
+        underTest
+        testScope.backgroundScope.launch {
+            kairos.activateSpec { underTest.activeSubChangedInGroupEvent.observe { eventCount++ } }
         }
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_3_ID_GROUPED)
+        testScope.runCurrent()
+
+        getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>(telephonyManager)
+            .onActiveDataSubscriptionIdChanged(SUB_1_ID)
+        testScope.runCurrent()
+
+        assertThat(eventCount).isEqualTo(0)
+    }
 
     @Test
-    fun anySimSecure_propagatesStateFromKeyguardUpdateMonitor() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.isAnySimSecure)
-            assertThat(latest).isFalse()
+    fun anySimSecure_propagatesStateFromKeyguardUpdateMonitor() = runTest {
+        val latest by underTest.isAnySimSecure.collectLastValue()
+        assertThat(latest).isFalse()
 
-            val updateMonitorCallback = argumentCaptor<KeyguardUpdateMonitorCallback>()
-            verify(updateMonitor).registerCallback(updateMonitorCallback.capture())
+        val updateMonitorCallback = argumentCaptor<KeyguardUpdateMonitorCallback>()
+        verify(keyguardUpdateMonitor).registerCallback(updateMonitorCallback.capture())
 
-            whenever(updateMonitor.isSimPinSecure).thenReturn(true)
-            updateMonitorCallback.value.onSimStateChanged(0, 0, 0)
+        keyguardUpdateMonitor.stub { on { isSimPinSecure } doReturn true }
+        updateMonitorCallback.lastValue.onSimStateChanged(0, 0, 0)
 
-            assertThat(latest).isTrue()
+        assertThat(latest).isTrue()
 
-            whenever(updateMonitor.isSimPinSecure).thenReturn(false)
-            updateMonitorCallback.value.onSimStateChanged(0, 0, 0)
+        keyguardUpdateMonitor.stub { on { isSimPinSecure } doReturn false }
+        updateMonitorCallback.lastValue.onSimStateChanged(0, 0, 0)
 
-            assertThat(latest).isFalse()
-        }
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun getIsAnySimSecure_delegatesCallToKeyguardUpdateMonitor() =
-        testScope.runTest {
-            assertThat(underTest.getIsAnySimSecure()).isFalse()
+    fun getIsAnySimSecure_delegatesCallToKeyguardUpdateMonitor() = runTest {
+        val anySimSecure by underTest.isAnySimSecure.collectLastValue()
 
-            whenever(updateMonitor.isSimPinSecure).thenReturn(true)
+        assertThat(anySimSecure).isFalse()
 
-            assertThat(underTest.getIsAnySimSecure()).isTrue()
-        }
+        keyguardUpdateMonitor.stub { on { isSimPinSecure } doReturn true }
+        argumentCaptor<KeyguardUpdateMonitorCallback>()
+            .apply { verify(keyguardUpdateMonitor).registerCallback(capture()) }
+            .lastValue
+            .onSimStateChanged(0, 0, 0)
+
+        assertThat(anySimSecure).isTrue()
+    }
 
     @Test
-    fun noSubscriptionsInEcmMode_notInEcmMode() =
-        testScope.runTest {
-            whenever(telephonyManager.emergencyCallbackMode).thenReturn(false)
+    fun noSubscriptionsInEcmMode_notInEcmMode() = runTest {
+        val latest by underTest.isInEcmMode.collectLastValue()
+        testScope.runCurrent()
 
-            runCurrent()
-
-            assertThat(underTest.isInEcmMode()).isFalse()
-        }
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun someSubscriptionsInEcmMode_inEcmMode() =
-        testScope.runTest {
-            whenever(telephonyManager.emergencyCallbackMode).thenReturn(true)
+    fun someSubscriptionsInEcmMode_inEcmMode() = runTest {
+        val latest by underTest.isInEcmMode.collectLastValue()
+        testScope.runCurrent()
 
-            runCurrent()
+        getTelephonyCallbackForType<EmergencyCallbackModeListener>(telephonyManager)
+            .onCallbackModeStarted(0, mock(), 0)
 
-            assertThat(underTest.isInEcmMode()).isTrue()
-        }
+        assertThat(latest).isTrue()
+    }
 
-    private fun TestScope.getDefaultNetworkCallback(): ConnectivityManager.NetworkCallback {
-        runCurrent()
+    private fun KairosTestScope.getDefaultNetworkCallback(): ConnectivityManager.NetworkCallback {
+        testScope.runCurrent()
         val callbackCaptor = argumentCaptor<ConnectivityManager.NetworkCallback>()
         verify(connectivityManager).registerDefaultNetworkCallback(callbackCaptor.capture())
-        return callbackCaptor.value!!
+        return callbackCaptor.lastValue
     }
 
-    private fun setWifiState(isCarrierMerged: Boolean) {
+    private fun KairosTestScope.setWifiState(isCarrierMerged: Boolean) {
         if (isCarrierMerged) {
             val mergedEntry =
-                mock<MergedCarrierEntry>().apply {
-                    whenever(this.isPrimaryNetwork).thenReturn(true)
-                    whenever(this.isDefaultNetwork).thenReturn(true)
-                    whenever(this.subscriptionId).thenReturn(SUB_CM_ID)
+                mock<MergedCarrierEntry> {
+                    on { isPrimaryNetwork } doReturn true
+                    on { isDefaultNetwork } doReturn true
+                    on { subscriptionId } doReturn SUB_CM_ID
                 }
-            whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
-            whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
+            wifiPickerTracker.stub {
+                on { mergedCarrierEntry } doReturn mergedEntry
+                on { connectedWifiEntry } doReturn null
+            }
         } else {
             val wifiEntry =
-                mock<WifiEntry>().apply {
-                    whenever(this.isPrimaryNetwork).thenReturn(true)
-                    whenever(this.isDefaultNetwork).thenReturn(true)
+                mock<WifiEntry> {
+                    on { isPrimaryNetwork } doReturn true
+                    on { isDefaultNetwork } doReturn true
                 }
-            whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
-            whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(null)
+            wifiPickerTracker.stub {
+                on { connectedWifiEntry } doReturn wifiEntry
+                on { mergedCarrierEntry } doReturn null
+            }
         }
-        wifiPickerTrackerCallback.value.onWifiEntriesChanged()
+        wifiPickerTrackerCallback.allValues.forEach { it.onWifiEntriesChanged() }
     }
 
-    private fun TestScope.getSubscriptionCallback():
-        SubscriptionManager.OnSubscriptionsChangedListener {
-        runCurrent()
-        val callbackCaptor = argumentCaptor<SubscriptionManager.OnSubscriptionsChangedListener>()
-        verify(subscriptionManager)
-            .addOnSubscriptionsChangedListener(any(), callbackCaptor.capture())
-        return callbackCaptor.value!!
-    }
-
-    private fun TestScope.getTelephonyCallbacks(): List<TelephonyCallback> {
-        runCurrent()
-        val callbackCaptor = argumentCaptor<TelephonyCallback>()
-        verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())
-        return callbackCaptor.allValues
-    }
-
-    private inline fun <reified T> TestScope.getTelephonyCallbackForType(): T {
-        val cbs = this.getTelephonyCallbacks().filterIsInstance<T>()
-        assertThat(cbs.size).isEqualTo(1)
-        return cbs[0]
+    private fun KairosTestScope.getSubscriptionCallback(): OnSubscriptionsChangedListener {
+        testScope.runCurrent()
+        return argumentCaptor<OnSubscriptionsChangedListener>()
+            .apply {
+                verify(subscriptionManager).addOnSubscriptionsChangedListener(any(), capture())
+            }
+            .lastValue
     }
 
     companion object {
@@ -1509,11 +1236,11 @@
         private const val SUB_1_NAME = "Carrier $SUB_1_ID"
         private val GROUP_1 = ParcelUuid(UUID.randomUUID())
         private val SUB_1 =
-            mock<SubscriptionInfo>().also {
-                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)
+            mock<SubscriptionInfo> {
+                on { subscriptionId } doReturn SUB_1_ID
+                on { groupUuid } doReturn GROUP_1
+                on { carrierName } doReturn SUB_1_NAME
+                on { profileClass } doReturn PROFILE_CLASS_UNSET
             }
         private val MODEL_1 =
             SubscriptionModel(
@@ -1528,11 +1255,11 @@
         private const val SUB_2_NAME = "Carrier $SUB_2_ID"
         private val GROUP_2 = ParcelUuid(UUID.randomUUID())
         private val SUB_2 =
-            mock<SubscriptionInfo>().also {
-                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)
+            mock<SubscriptionInfo> {
+                on { subscriptionId } doReturn SUB_2_ID
+                on { groupUuid } doReturn GROUP_2
+                on { carrierName } doReturn SUB_2_NAME
+                on { profileClass } doReturn PROFILE_CLASS_UNSET
             }
         private val MODEL_2 =
             SubscriptionModel(
@@ -1548,34 +1275,34 @@
         // Subscription 3
         private const val SUB_3_ID_GROUPED = 3
         private val SUB_3 =
-            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)
+            mock<SubscriptionInfo> {
+                on { subscriptionId } doReturn SUB_3_ID_GROUPED
+                on { groupUuid } doReturn GROUP_ID_3_4
+                on { profileClass } doReturn PROFILE_CLASS_UNSET
             }
 
         // Subscription 4
         private const val SUB_4_ID_GROUPED = 4
         private val SUB_4 =
-            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)
+            mock<SubscriptionInfo> {
+                on { subscriptionId } doReturn SUB_4_ID_GROUPED
+                on { groupUuid } doReturn GROUP_ID_3_4
+                on { profileClass } doReturn PROFILE_CLASS_UNSET
             }
 
         // Subs 3 and 4 are considered to be in the same group ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
         private const val NET_ID = 123
-        private val NETWORK = mock<Network>().apply { whenever(getNetId()).thenReturn(NET_ID) }
+        private val NETWORK = mock<Network> { on { getNetId() } doReturn NET_ID }
 
         // Carrier merged subscription
         private const val SUB_CM_ID = 5
         private const val SUB_CM_NAME = "Carrier $SUB_CM_ID"
         private val SUB_CM =
-            mock<SubscriptionInfo>().also {
-                whenever(it.subscriptionId).thenReturn(SUB_CM_ID)
-                whenever(it.carrierName).thenReturn(SUB_CM_NAME)
-                whenever(it.profileClass).thenReturn(PROFILE_CLASS_UNSET)
+            mock<SubscriptionInfo> {
+                on { subscriptionId } doReturn SUB_CM_ID
+                on { carrierName } doReturn SUB_CM_NAME
+                on { profileClass } doReturn PROFILE_CLASS_UNSET
             }
         private val MODEL_CM =
             SubscriptionModel(
@@ -1585,28 +1312,29 @@
             )
 
         private val WIFI_INFO_CM =
-            mock<WifiInfo>().apply {
-                whenever(this.isPrimary).thenReturn(true)
-                whenever(this.isCarrierMerged).thenReturn(true)
-                whenever(this.subscriptionId).thenReturn(SUB_CM_ID)
+            mock<WifiInfo> {
+                on { isPrimary } doReturn true
+                on { isCarrierMerged } doReturn true
+                on { subscriptionId } doReturn SUB_CM_ID
             }
         private val WIFI_NETWORK_CAPS_CM =
-            mock<NetworkCapabilities>().also {
-                whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                whenever(it.transportInfo).thenReturn(WIFI_INFO_CM)
-                whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(true)
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_WIFI) } doReturn true
+                on { transportInfo } doReturn WIFI_INFO_CM
+                on { hasCapability(NET_CAPABILITY_VALIDATED) } doReturn true
             }
 
         private val WIFI_INFO_ACTIVE =
-            mock<WifiInfo>().apply {
-                whenever(this.isPrimary).thenReturn(true)
-                whenever(this.isCarrierMerged).thenReturn(false)
+            mock<WifiInfo> {
+                on { isPrimary } doReturn true
+                on { isCarrierMerged } doReturn false
             }
+
         private val WIFI_NETWORK_CAPS_ACTIVE =
-            mock<NetworkCapabilities>().also {
-                whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
-                whenever(it.transportInfo).thenReturn(WIFI_INFO_ACTIVE)
-                whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(true)
+            Mockito.mock(NetworkCapabilities::class.java).stub {
+                on { hasTransport(TRANSPORT_WIFI) } doReturn true
+                on { transportInfo } doReturn WIFI_INFO_ACTIVE
+                on { hasCapability(NET_CAPABILITY_VALIDATED) } doReturn true
             }
 
         /**
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
index 9fddbfb..a154694 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
@@ -16,6 +16,11 @@
 
 package com.android.systemui.log.table
 
+import com.android.systemui.kairos.BuildScope
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.changes
+import com.android.systemui.kairos.effect
 import com.android.systemui.util.kotlin.pairwiseBy
 import kotlinx.coroutines.flow.Flow
 
@@ -184,3 +189,94 @@
         newVal
     }
 }
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
+@ExperimentalKairosApi
+@JvmName("logIntDiffsForTable")
+fun BuildScope.logDiffsForTable(
+    intState: State<Int?>,
+    tableLogBuffer: TableLogBuffer,
+    columnPrefix: String = "",
+    columnName: String,
+) {
+    var isInitial = true
+    intState.observe { new ->
+        tableLogBuffer.logChange(columnPrefix, columnName, new, isInitial = isInitial)
+        isInitial = false
+    }
+}
+
+/**
+ * Each time the flow is updated with a new value, logs the differences between the previous value
+ * and the new value to the given [tableLogBuffer].
+ *
+ * The new value's [Diffable.logDiffs] method will be used to log the differences to the table.
+ *
+ * @param columnPrefix a prefix that will be applied to every column name that gets logged.
+ */
+@ExperimentalKairosApi
+fun <T : Diffable<T>> BuildScope.logDiffsForTable(
+    diffableState: State<T>,
+    tableLogBuffer: TableLogBuffer,
+    columnPrefix: String = "",
+) {
+    val initialValue = diffableState.sampleDeferred()
+    effect {
+        // Fully log the initial value to the table.
+        tableLogBuffer.logChange(columnPrefix, isInitial = true) { row ->
+            initialValue.value.logFull(row)
+        }
+    }
+    diffableState.changes.observe { newState ->
+        val prevState = diffableState.sample()
+        tableLogBuffer.logDiffs(columnPrefix, prevVal = prevState, newVal = newState)
+    }
+}
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
+@ExperimentalKairosApi
+@JvmName("logBooleanDiffsForTable")
+fun BuildScope.logDiffsForTable(
+    booleanState: State<Boolean>,
+    tableLogBuffer: TableLogBuffer,
+    columnPrefix: String = "",
+    columnName: String,
+) {
+    var isInitial = true
+    booleanState.observe { new ->
+        tableLogBuffer.logChange(columnPrefix, columnName, new, isInitial = isInitial)
+        isInitial = false
+    }
+}
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
+@ExperimentalKairosApi
+@JvmName("logStringDiffsForTable")
+fun BuildScope.logDiffsForTable(
+    stringState: State<String?>,
+    tableLogBuffer: TableLogBuffer,
+    columnPrefix: String = "",
+    columnName: String,
+) {
+    var isInitial = true
+    stringState.observe { new ->
+        tableLogBuffer.logChange(columnPrefix, columnName, new, isInitial = isInitial)
+        isInitial = false
+    }
+}
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
+@ExperimentalKairosApi
+@JvmName("logListDiffsForTable")
+fun <T> BuildScope.logDiffsForTable(
+    listState: State<List<T>>,
+    tableLogBuffer: TableLogBuffer,
+    columnPrefix: String = "",
+    columnName: String,
+) {
+    var isInitial = true
+    listState.observe { new ->
+        tableLogBuffer.logChange(columnPrefix, columnName, new.toString(), isInitial = isInitial)
+        isInitial = false
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index a18495e..61c0055 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.CoreStartable
 import com.android.systemui.Flags
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.kairos.ExperimentalKairosApi
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogBufferFactory
 import com.android.systemui.log.table.TableLogBuffer
@@ -36,8 +37,12 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepositoryImpl
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepositoryKairosAdapter
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileRepositorySwitcher
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileRepositorySwitcherKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoModeMobileConnectionDataSourceKairosImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionRepositoryKairosFactoryImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryKairosImpl
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorImpl
 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter
@@ -79,7 +84,17 @@
 import javax.inject.Provider
 import kotlinx.coroutines.flow.Flow
 
-@Module
+@OptIn(ExperimentalKairosApi::class)
+@Module(
+    includes =
+        [
+            DemoModeMobileConnectionDataSourceKairosImpl.Module::class,
+            MobileRepositorySwitcherKairos.Module::class,
+            MobileConnectionsRepositoryKairosImpl.Module::class,
+            MobileConnectionRepositoryKairosFactoryImpl.Module::class,
+            MobileConnectionsRepositoryKairosAdapter.Module::class,
+        ]
+)
 abstract class StatusBarPipelineModule {
     @Binds
     abstract fun airplaneModeRepository(impl: AirplaneModeRepositoryImpl): AirplaneModeRepository
@@ -158,7 +173,7 @@
         @Provides
         fun mobileConnectionsRepository(
             impl: Provider<MobileRepositorySwitcher>,
-            kairosImpl: Provider<MobileRepositorySwitcherKairos>,
+            kairosImpl: Provider<MobileConnectionsRepositoryKairosAdapter>,
         ): MobileConnectionsRepository {
             return if (Flags.statusBarMobileIconKairos()) {
                 kairosImpl.get()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepositoryKairos.kt
index 8e53f64..2e79626 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepositoryKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepositoryKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,39 +17,39 @@
 package com.android.systemui.statusbar.pipeline.mobile.data.repository
 
 import android.telephony.CellSignalStrength
-import android.telephony.SubscriptionInfo
 import android.telephony.TelephonyManager
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
-import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import kotlinx.coroutines.flow.StateFlow
 
 /**
  * Every mobile line of service can be identified via a [SubscriptionInfo] object. We set up a
  * repository for each individual, tracked subscription via [MobileConnectionsRepository], and this
  * repository is responsible for setting up a [TelephonyManager] object tied to its subscriptionId
  *
- * There should only ever be one [MobileConnectionRepositoryKairos] per subscription, since
+ * There should only ever be one [MobileConnectionRepository] per subscription, since
  * [TelephonyManager] limits the number of callbacks that can be registered per process.
  *
  * This repository should have all of the relevant information for a single line of service, which
  * eventually becomes a single icon in the status bar.
  */
+@ExperimentalKairosApi
 interface MobileConnectionRepositoryKairos {
     /** The subscriptionId that this connection represents */
     val subId: Int
 
     /** The carrierId for this connection. See [TelephonyManager.getSimCarrierId] */
-    val carrierId: StateFlow<Int>
+    val carrierId: State<Int>
 
     /** Reflects the value from the carrier config INFLATE_SIGNAL_STRENGTH for this connection */
-    val inflateSignalStrength: StateFlow<Boolean>
+    val inflateSignalStrength: State<Boolean>
 
     /** Carrier config KEY_SHOW_5G_SLICE_ICON_BOOL for this connection */
-    val allowNetworkSliceIndicator: StateFlow<Boolean>
+    val allowNetworkSliceIndicator: State<Boolean>
 
     /**
      * The table log buffer created for this connection. Will have the name "MobileConnectionLog
@@ -58,17 +58,17 @@
     val tableLogBuffer: TableLogBuffer
 
     /** True if the [android.telephony.ServiceState] says this connection is emergency calls only */
-    val isEmergencyOnly: StateFlow<Boolean>
+    val isEmergencyOnly: State<Boolean>
 
     /** True if [android.telephony.ServiceState] says we are roaming */
-    val isRoaming: StateFlow<Boolean>
+    val isRoaming: State<Boolean>
 
     /**
      * See [android.telephony.ServiceState.getOperatorAlphaShort], this value is defined as the
      * current registered operator name in short alphanumeric format. In some cases this name might
      * be preferred over other methods of calculating the network name
      */
-    val operatorAlphaShort: StateFlow<String?>
+    val operatorAlphaShort: State<String?>
 
     /**
      * TODO (b/263167683): Clarify this field
@@ -78,7 +78,7 @@
      * connection to be in-service if either the voice registration state is IN_SERVICE or the data
      * registration state is IN_SERVICE and NOT IWLAN.
      */
-    val isInService: StateFlow<Boolean>
+    val isInService: State<Boolean>
 
     /**
      * True if this subscription is actively connected to a non-terrestrial network and false
@@ -91,48 +91,48 @@
      * during the lifetime of a subscription but [SubscriptionModel.isExclusivelyNonTerrestrial]
      * will stay constant.
      */
-    val isNonTerrestrial: StateFlow<Boolean>
+    val isNonTerrestrial: State<Boolean>
 
     /** True if [android.telephony.SignalStrength] told us that this connection is using GSM */
-    val isGsm: StateFlow<Boolean>
+    val isGsm: State<Boolean>
 
     /**
      * There is still specific logic in the pipeline that calls out CDMA level explicitly. This
      * field is not completely orthogonal to [primaryLevel], because CDMA could be primary.
      */
     // @IntRange(from = 0, to = 4)
-    val cdmaLevel: StateFlow<Int>
+    val cdmaLevel: State<Int>
 
     /** [android.telephony.SignalStrength]'s concept of the overall signal level */
     // @IntRange(from = 0, to = 4)
-    val primaryLevel: StateFlow<Int>
+    val primaryLevel: State<Int>
 
     /**
      * This level can be used to reflect the signal strength when in carrier roaming NTN mode
      * (carrier-based satellite)
      */
-    val satelliteLevel: StateFlow<Int>
+    val satelliteLevel: State<Int>
 
     /** The current data connection state. See [DataConnectionState] */
-    val dataConnectionState: StateFlow<DataConnectionState>
+    val dataConnectionState: State<DataConnectionState>
 
     /** The current data activity direction. See [DataActivityModel] */
-    val dataActivityDirection: StateFlow<DataActivityModel>
+    val dataActivityDirection: State<DataActivityModel>
 
     /** True if there is currently a carrier network change in process */
-    val carrierNetworkChangeActive: StateFlow<Boolean>
+    val carrierNetworkChangeActive: State<Boolean>
 
     /**
      * [resolvedNetworkType] is the [TelephonyDisplayInfo.getOverrideNetworkType] if it exists or
      * [TelephonyDisplayInfo.getNetworkType]. This is used to look up the proper network type icon
      */
-    val resolvedNetworkType: StateFlow<ResolvedNetworkType>
+    val resolvedNetworkType: State<ResolvedNetworkType>
 
     /** The total number of levels. Used with [SignalDrawable]. */
-    val numberOfLevels: StateFlow<Int>
+    val numberOfLevels: State<Int>
 
     /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */
-    val dataEnabled: StateFlow<Boolean>
+    val dataEnabled: State<Boolean>
 
     /**
      * See [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber]. This bit only matters if
@@ -140,10 +140,10 @@
      *
      * True if the Enhanced Roaming Indicator (ERI) display number is not [TelephonyManager.ERI_OFF]
      */
-    val cdmaRoaming: StateFlow<Boolean>
+    val cdmaRoaming: State<Boolean>
 
     /** The service provider name for this network connection, or the default name. */
-    val networkName: StateFlow<NetworkNameModel>
+    val networkName: State<NetworkNameModel>
 
     /**
      * The service provider name for this network connection, or the default name.
@@ -151,25 +151,25 @@
      * TODO(b/296600321): De-duplicate this field with [networkName] after determining the data
      *   provided is identical
      */
-    val carrierName: StateFlow<NetworkNameModel>
+    val carrierName: State<NetworkNameModel>
 
     /**
      * True if this type of connection is allowed while airplane mode is on, and false otherwise.
      */
-    val isAllowedDuringAirplaneMode: StateFlow<Boolean>
+    val isAllowedDuringAirplaneMode: State<Boolean>
 
     /**
      * True if this network has NET_CAPABILITIY_PRIORITIZE_LATENCY, and can be considered to be a
      * network slice
      */
-    val hasPrioritizedNetworkCapabilities: StateFlow<Boolean>
+    val hasPrioritizedNetworkCapabilities: State<Boolean>
 
     /**
      * True if this connection is in emergency callback mode.
      *
      * @see [TelephonyManager.getEmergencyCallbackMode]
      */
-    suspend fun isInEcmMode(): Boolean
+    val isInEcmMode: State<Boolean>
 
     companion object {
         /** The default number of levels to use for [numberOfLevels]. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepositoryKairos.kt
index b3cbbfd..79bfb6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepositoryKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepositoryKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,35 +21,42 @@
 import com.android.settingslib.SignalIcon.MobileIconGroup
 import com.android.settingslib.mobile.MobileMappings
 import com.android.settingslib.mobile.MobileMappings.Config
+import com.android.systemui.kairos.Events
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.Incremental
+import com.android.systemui.kairos.State
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
 
 /**
  * Repo for monitoring the complete active subscription info list, to be consumed and filtered based
  * on various policy
  */
+@ExperimentalKairosApi
 interface MobileConnectionsRepositoryKairos {
+
+    /** All active mobile connections. */
+    val mobileConnectionsBySubId: Incremental<Int, MobileConnectionRepositoryKairos>
+
     /** Observable list of current mobile subscriptions */
-    val subscriptions: StateFlow<List<SubscriptionModel>>
+    val subscriptions: State<Collection<SubscriptionModel>>
 
     /**
      * Observable for the subscriptionId of the current mobile data connection. Null if we don't
      * have a valid subscription id
      */
-    val activeMobileDataSubscriptionId: StateFlow<Int?>
+    val activeMobileDataSubscriptionId: State<Int?>
 
     /** Repo that tracks the current [activeMobileDataSubscriptionId] */
-    val activeMobileDataRepository: StateFlow<MobileConnectionRepository?>
+    val activeMobileDataRepository: State<MobileConnectionRepositoryKairos?>
 
     /**
      * Observable event for when the active data sim switches but the group stays the same. E.g.,
      * CBRS switching would trigger this
      */
-    val activeSubChangedInGroupEvent: Flow<Unit>
+    val activeSubChangedInGroupEvent: Events<Unit>
 
-    /** Tracks [SubscriptionManager.getDefaultDataSubscriptionId]. Null if there is no default */
-    val defaultDataSubId: StateFlow<Int?>
+    /** Tracks [SubscriptionManager.getDefaultDataSubscriptionId]. `null` if there is no default. */
+    val defaultDataSubId: State<Int?>
 
     /**
      * True if the default network connection is a mobile-like connection and false otherwise.
@@ -58,20 +65,17 @@
      * there are edge cases (like carrier merged wifi) that could also result in the default
      * connection being mobile-like.
      */
-    val mobileIsDefault: StateFlow<Boolean>
+    val mobileIsDefault: State<Boolean>
 
     /**
      * True if the device currently has a carrier merged connection.
      *
      * See [CarrierMergedConnectionRepository] for more info.
      */
-    val hasCarrierMergedConnection: Flow<Boolean>
+    val hasCarrierMergedConnection: State<Boolean>
 
     /** True if the default network connection is validated and false otherwise. */
-    val defaultConnectionIsValidated: StateFlow<Boolean>
-
-    /** Get or create a repository for the line of service for the given subscription ID */
-    fun getRepoForSubId(subId: Int): MobileConnectionRepository
+    val defaultConnectionIsValidated: State<Boolean>
 
     /**
      * [Config] is an object that tracks relevant configuration flags for a given subscription ID.
@@ -83,13 +87,13 @@
      *
      * This flow will produce whenever the default data subscription or the carrier config changes.
      */
-    val defaultDataSubRatConfig: StateFlow<Config>
+    val defaultDataSubRatConfig: State<Config>
 
     /** The icon mapping from network type to [MobileIconGroup] for the default subscription */
-    val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>>
+    val defaultMobileIconMapping: State<Map<String, MobileIconGroup>>
 
     /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
-    val defaultMobileIconGroup: Flow<MobileIconGroup>
+    val defaultMobileIconGroup: State<MobileIconGroup>
 
     /**
      * Can the device make emergency calls using the device-based service state? This field is only
@@ -100,7 +104,7 @@
      *
      * This is an eager flow, and re-evaluates whenever ACTION_SERVICE_STATE is sent for subId = -1.
      */
-    val isDeviceEmergencyCallCapable: StateFlow<Boolean>
+    val isDeviceEmergencyCallCapable: State<Boolean>
 
     /**
      * If any active SIM on the device is in
@@ -108,22 +112,11 @@
      * [android.telephony.TelephonyManager.SIM_STATE_PUK_REQUIRED] or
      * [android.telephony.TelephonyManager.SIM_STATE_PERM_DISABLED]
      */
-    val isAnySimSecure: Flow<Boolean>
-
-    /**
-     * Returns whether any active SIM on the device is in
-     * [android.telephony.TelephonyManager.SIM_STATE_PIN_REQUIRED] or
-     * [android.telephony.TelephonyManager.SIM_STATE_PUK_REQUIRED] or
-     * [android.telephony.TelephonyManager.SIM_STATE_PERM_DISABLED].
-     *
-     * Note: Unfortunately, we cannot name this [isAnySimSecure] due to a conflict with the flow
-     * name above (Java code-gen is having issues with it).
-     */
-    fun getIsAnySimSecure(): Boolean
+    val isAnySimSecure: State<Boolean>
 
     /**
      * Checks if any subscription has [android.telephony.TelephonyManager.getEmergencyCallbackMode]
      * == true
      */
-    suspend fun isInEcmMode(): Boolean
+    val isInEcmMode: State<Boolean>
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepositoryKairosAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepositoryKairosAdapter.kt
new file mode 100644
index 0000000..64144d9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepositoryKairosAdapter.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository
+
+import android.content.Context
+import com.android.settingslib.SignalIcon
+import com.android.settingslib.mobile.MobileMappings
+import com.android.systemui.Flags
+import com.android.systemui.KairosActivatable
+import com.android.systemui.KairosBuilder
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosNetwork
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapValues
+import com.android.systemui.kairos.toColdConflatedFlow
+import com.android.systemui.kairosBuilder
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionRepositoryKairosAdapter
+import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
+import dagger.Provides
+import dagger.multibindings.ElementsIntoSet
+import javax.inject.Inject
+import javax.inject.Provider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
+
+@ExperimentalKairosApi
+@SysUISingleton
+class MobileConnectionsRepositoryKairosAdapter
+@Inject
+constructor(
+    private val kairosRepo: MobileConnectionsRepositoryKairos,
+    private val kairosNetwork: KairosNetwork,
+    @Application scope: CoroutineScope,
+    connectivityRepository: ConnectivityRepository,
+    context: Context,
+    carrierConfigRepo: CarrierConfigRepository,
+) : MobileConnectionsRepository, KairosBuilder by kairosBuilder() {
+    override val subscriptions: StateFlow<List<SubscriptionModel>> =
+        kairosRepo.subscriptions
+            .map { it.toList() }
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
+
+    override val activeMobileDataSubscriptionId: StateFlow<Int?> =
+        kairosRepo.activeMobileDataSubscriptionId
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+
+    private val reposBySubIdK = buildIncremental {
+        kairosRepo.mobileConnectionsBySubId
+            .mapValues { (subId, repo) ->
+                buildSpec {
+                    MobileConnectionRepositoryKairosAdapter(
+                        kairosRepo = repo,
+                        carrierConfig = carrierConfigRepo.getOrCreateConfigForSubId(subId),
+                    )
+                }
+            }
+            .applyLatestSpecForKey()
+    }
+
+    private val reposBySubId =
+        reposBySubIdK
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(scope, SharingStarted.Eagerly, emptyMap())
+
+    override val activeMobileDataRepository: StateFlow<MobileConnectionRepository?> =
+        combine(kairosRepo.activeMobileDataSubscriptionId, reposBySubIdK) { id, repos -> repos[id] }
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+
+    override val activeSubChangedInGroupEvent: Flow<Unit> =
+        kairosRepo.activeSubChangedInGroupEvent.toColdConflatedFlow(kairosNetwork)
+
+    override val defaultDataSubId: StateFlow<Int?> =
+        kairosRepo.defaultDataSubId
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+
+    override val mobileIsDefault: StateFlow<Boolean> =
+        kairosRepo.mobileIsDefault
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                connectivityRepository.defaultConnections.value.mobile.isDefault,
+            )
+
+    override val hasCarrierMergedConnection: Flow<Boolean> =
+        kairosRepo.hasCarrierMergedConnection.toColdConflatedFlow(kairosNetwork)
+
+    override val defaultConnectionIsValidated: StateFlow<Boolean> =
+        kairosRepo.defaultConnectionIsValidated
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                connectivityRepository.defaultConnections.value.isValidated,
+            )
+
+    override fun getRepoForSubId(subId: Int): MobileConnectionRepository =
+        reposBySubId.value[subId] ?: error("Unknown subscription id: $subId")
+
+    override val defaultDataSubRatConfig: StateFlow<MobileMappings.Config> =
+        kairosRepo.defaultDataSubRatConfig
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                MobileMappings.Config.readConfig(context),
+            )
+
+    override val defaultMobileIconMapping: Flow<Map<String, SignalIcon.MobileIconGroup>> =
+        kairosRepo.defaultMobileIconMapping.toColdConflatedFlow(kairosNetwork)
+
+    override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> =
+        kairosRepo.defaultMobileIconGroup.toColdConflatedFlow(kairosNetwork)
+
+    override val isDeviceEmergencyCallCapable: StateFlow<Boolean> =
+        kairosRepo.isDeviceEmergencyCallCapable
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(scope, SharingStarted.Eagerly, false)
+
+    override val isAnySimSecure: StateFlow<Boolean> =
+        kairosRepo.isAnySimSecure
+            .toColdConflatedFlow(kairosNetwork)
+            .stateIn(scope, SharingStarted.Eagerly, false)
+
+    override fun getIsAnySimSecure(): Boolean = isAnySimSecure.value
+
+    override suspend fun isInEcmMode(): Boolean =
+        kairosNetwork.transact { kairosRepo.isInEcmMode.sample() }
+
+    @dagger.Module
+    object Module {
+        @Provides
+        @ElementsIntoSet
+        fun kairosActivatable(
+            impl: Provider<MobileConnectionsRepositoryKairosAdapter>
+        ): Set<@JvmSuppressWildcards KairosActivatable> =
+            if (Flags.statusBarMobileIconKairos()) setOf(impl.get()) else emptySet()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairos.kt
index 3c855a9..1f5b849 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,23 +20,32 @@
 import androidx.annotation.VisibleForTesting
 import com.android.settingslib.SignalIcon
 import com.android.settingslib.mobile.MobileMappings
+import com.android.systemui.Flags
+import com.android.systemui.KairosActivatable
+import com.android.systemui.KairosBuilder
+import com.android.systemui.activated
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.demomode.DemoMode
 import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.kairos.Events
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.Incremental
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.flatMap
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.switchEvents
+import com.android.systemui.kairos.switchIncremental
+import com.android.systemui.kairosBuilder
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryKairosImpl
+import dagger.Binds
+import dagger.Provides
+import dagger.multibindings.ElementsIntoSet
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
+import javax.inject.Provider
 import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.stateIn
 
 /**
  * A provider for the [MobileConnectionsRepository] interface that can choose between the Demo and
@@ -60,18 +69,17 @@
  * a change (due to `distinctUntilChanged`) and will not refresh their data providers to the demo
  * implementation.
  */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@ExperimentalKairosApi
 @SysUISingleton
 class MobileRepositorySwitcherKairos
 @Inject
 constructor(
-    @Background scope: CoroutineScope,
-    val realRepository: MobileConnectionsRepositoryImpl,
-    val demoMobileConnectionsRepository: DemoMobileConnectionsRepository,
+    private val realRepository: MobileConnectionsRepositoryKairosImpl,
+    private val demoRepositoryFactory: DemoMobileConnectionsRepositoryKairos.Factory,
     demoModeController: DemoModeController,
-) : MobileConnectionsRepository {
+) : MobileConnectionsRepositoryKairos, KairosBuilder by kairosBuilder() {
 
-    val isDemoMode: StateFlow<Boolean> =
+    private val isDemoMode: State<Boolean> = buildState {
         conflatedCallbackFlow {
                 val callback =
                     object : DemoMode {
@@ -80,12 +88,10 @@
                         }
 
                         override fun onDemoModeStarted() {
-                            demoMobileConnectionsRepository.startProcessingCommands()
                             trySend(true)
                         }
 
                         override fun onDemoModeFinished() {
-                            demoMobileConnectionsRepository.stopProcessingCommands()
                             trySend(false)
                         }
                     }
@@ -93,114 +99,73 @@
                 demoModeController.addCallback(callback)
                 awaitClose { demoModeController.removeCallback(callback) }
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), demoModeController.isInDemoMode)
+            .toState(demoModeController.isInDemoMode)
+    }
 
     // Convenient definition flow for the currently active repo (based on demo mode or not)
     @VisibleForTesting
-    val activeRepo: StateFlow<MobileConnectionsRepository> =
-        isDemoMode
-            .mapLatest { demoMode ->
-                if (demoMode) {
-                    demoMobileConnectionsRepository
-                } else {
-                    realRepository
-                }
+    val activeRepo: State<MobileConnectionsRepositoryKairos> = buildState {
+        isDemoMode.mapLatestBuild { demoMode ->
+            if (demoMode) {
+                activated { demoRepositoryFactory.create() }
+            } else {
+                realRepository
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), realRepository)
-
-    override val subscriptions: StateFlow<List<SubscriptionModel>> =
-        activeRepo
-            .flatMapLatest { it.subscriptions }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.subscriptions.value)
-
-    override val activeMobileDataSubscriptionId: StateFlow<Int?> =
-        activeRepo
-            .flatMapLatest { it.activeMobileDataSubscriptionId }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                realRepository.activeMobileDataSubscriptionId.value,
-            )
-
-    override val activeMobileDataRepository: StateFlow<MobileConnectionRepository?> =
-        activeRepo
-            .flatMapLatest { it.activeMobileDataRepository }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                realRepository.activeMobileDataRepository.value,
-            )
-
-    override val activeSubChangedInGroupEvent: Flow<Unit> =
-        activeRepo.flatMapLatest { it.activeSubChangedInGroupEvent }
-
-    override val defaultDataSubRatConfig: StateFlow<MobileMappings.Config> =
-        activeRepo
-            .flatMapLatest { it.defaultDataSubRatConfig }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                realRepository.defaultDataSubRatConfig.value,
-            )
-
-    override val defaultMobileIconMapping: Flow<Map<String, SignalIcon.MobileIconGroup>> =
-        activeRepo.flatMapLatest { it.defaultMobileIconMapping }
-
-    override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> =
-        activeRepo.flatMapLatest { it.defaultMobileIconGroup }
-
-    override val isDeviceEmergencyCallCapable: StateFlow<Boolean> =
-        activeRepo
-            .flatMapLatest { it.isDeviceEmergencyCallCapable }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                realRepository.isDeviceEmergencyCallCapable.value,
-            )
-
-    override val isAnySimSecure: Flow<Boolean> = activeRepo.flatMapLatest { it.isAnySimSecure }
-
-    override fun getIsAnySimSecure(): Boolean = activeRepo.value.getIsAnySimSecure()
-
-    override val defaultDataSubId: StateFlow<Int?> =
-        activeRepo
-            .flatMapLatest { it.defaultDataSubId }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.defaultDataSubId.value)
-
-    override val mobileIsDefault: StateFlow<Boolean> =
-        activeRepo
-            .flatMapLatest { it.mobileIsDefault }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.mobileIsDefault.value)
-
-    override val hasCarrierMergedConnection: StateFlow<Boolean> =
-        activeRepo
-            .flatMapLatest { it.hasCarrierMergedConnection }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                realRepository.hasCarrierMergedConnection.value,
-            )
-
-    override val defaultConnectionIsValidated: StateFlow<Boolean> =
-        activeRepo
-            .flatMapLatest { it.defaultConnectionIsValidated }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                realRepository.defaultConnectionIsValidated.value,
-            )
-
-    override fun getRepoForSubId(subId: Int): MobileConnectionRepository {
-        if (isDemoMode.value) {
-            return demoMobileConnectionsRepository.getRepoForSubId(subId)
         }
-        return realRepository.getRepoForSubId(subId)
     }
 
-    override suspend fun isInEcmMode(): Boolean =
-        if (isDemoMode.value) {
-            demoMobileConnectionsRepository.isInEcmMode()
-        } else {
-            realRepository.isInEcmMode()
+    override val mobileConnectionsBySubId: Incremental<Int, MobileConnectionRepositoryKairos> =
+        activeRepo.map { it.mobileConnectionsBySubId }.switchIncremental()
+
+    override val subscriptions: State<Collection<SubscriptionModel>> =
+        activeRepo.flatMap { it.subscriptions }
+
+    override val activeMobileDataSubscriptionId: State<Int?> =
+        activeRepo.flatMap { it.activeMobileDataSubscriptionId }
+
+    override val activeMobileDataRepository: State<MobileConnectionRepositoryKairos?> =
+        activeRepo.flatMap { it.activeMobileDataRepository }
+
+    override val activeSubChangedInGroupEvent: Events<Unit> =
+        activeRepo.map { it.activeSubChangedInGroupEvent }.switchEvents()
+
+    override val defaultDataSubRatConfig: State<MobileMappings.Config> =
+        activeRepo.flatMap { it.defaultDataSubRatConfig }
+
+    override val defaultMobileIconMapping: State<Map<String, SignalIcon.MobileIconGroup>> =
+        activeRepo.flatMap { it.defaultMobileIconMapping }
+
+    override val defaultMobileIconGroup: State<SignalIcon.MobileIconGroup> =
+        activeRepo.flatMap { it.defaultMobileIconGroup }
+
+    override val isDeviceEmergencyCallCapable: State<Boolean> =
+        activeRepo.flatMap { it.isDeviceEmergencyCallCapable }
+
+    override val isAnySimSecure: State<Boolean> = activeRepo.flatMap { it.isAnySimSecure }
+
+    override val defaultDataSubId: State<Int?> = activeRepo.flatMap { it.defaultDataSubId }
+
+    override val mobileIsDefault: State<Boolean> = activeRepo.flatMap { it.mobileIsDefault }
+
+    override val hasCarrierMergedConnection: State<Boolean> =
+        activeRepo.flatMap { it.hasCarrierMergedConnection }
+
+    override val defaultConnectionIsValidated: State<Boolean> =
+        activeRepo.flatMap { it.defaultConnectionIsValidated }
+
+    override val isInEcmMode: State<Boolean> = activeRepo.flatMap { it.isInEcmMode }
+
+    @dagger.Module
+    interface Module {
+        @Binds fun bindImpl(impl: MobileRepositorySwitcherKairos): MobileConnectionsRepositoryKairos
+
+        companion object {
+            @Provides
+            @ElementsIntoSet
+            fun kairosActivatable(
+                impl: Provider<MobileRepositorySwitcherKairos>
+            ): Set<@JvmSuppressWildcards KairosActivatable> =
+                if (Flags.statusBarMobileIconKairos()) setOf(impl.get()) else emptySet()
         }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepositoryKairos.kt
index 712ebdc..a244feb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepositoryKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionRepositoryKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,38 +16,46 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.data.repository.demo
 
-import android.telephony.CellSignalStrength
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import android.telephony.TelephonyManager
+import com.android.settingslib.SignalIcon
+import com.android.systemui.KairosBuilder
+import com.android.systemui.kairos.Events
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.TransactionScope
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapCheap
+import com.android.systemui.kairos.mergeLeft
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairos.util.Either
+import com.android.systemui.kairos.util.Either.First
+import com.android.systemui.kairos.util.Either.Second
+import com.android.systemui.kairos.util.firstOrNull
+import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CARRIER_ID
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CARRIER_NETWORK_CHANGE
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CDMA_LEVEL
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_EMERGENCY
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_IS_GSM
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_IS_IN_SERVICE
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_IS_NTN
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_OPERATOR
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_PRIMARY_LEVEL
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_ROAMING
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_SATELLITE_LEVEL
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile as FakeMobileEvent
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_CARRIER_ID
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_CARRIER_NETWORK_CHANGE
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_CDMA_LEVEL
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_IS_IN_SERVICE
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_IS_NTN
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_OPERATOR
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_PRIMARY_LEVEL
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_ROAMING
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepositoryKairos.Companion.COL_SATELLITE_LEVEL
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
-import kotlinx.coroutines.CoroutineScope
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel.CarrierMerged as FakeCarrierMergedEvent
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
 
 /**
  * Demo version of [MobileConnectionRepository]. Note that this class shares all of its flows using
@@ -55,241 +63,206 @@
  * [MutableStateFlow] while still logging all of the inputs in the same manor as the production
  * repos.
  */
+@ExperimentalKairosApi
 class DemoMobileConnectionRepositoryKairos(
     override val subId: Int,
     override val tableLogBuffer: TableLogBuffer,
-    val scope: CoroutineScope,
-) : MobileConnectionRepository, MobileConnectionRepositoryKairos {
-    private val _carrierId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
-    override val carrierId =
-        _carrierId
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_CARRIER_ID,
-                initialValue = _carrierId.value,
+    mobileEvents: Events<FakeMobileEvent>,
+    carrierMergedResetEvents: Events<Any?>,
+    wifiEvents: Events<FakeCarrierMergedEvent>,
+    private val mobileMappingsReverseLookup: State<Map<SignalIcon.MobileIconGroup, String>>,
+) : MobileConnectionRepositoryKairos, KairosBuilder by kairosBuilder() {
+
+    private val initialState =
+        FakeMobileEvent(
+            level = null,
+            dataType = null,
+            subId = subId,
+            carrierId = null,
+            activity = null,
+            carrierNetworkChange = false,
+            roaming = false,
+            name = DEMO_CARRIER_NAME,
+        )
+
+    private val lastMobileEvent: State<FakeMobileEvent> = buildState {
+        mobileEvents.holdState(initialState)
+    }
+
+    private val lastEvent: State<Either<FakeMobileEvent, FakeCarrierMergedEvent>> = buildState {
+        mergeLeft(
+                mobileEvents.mapCheap { First(it) },
+                wifiEvents.mapCheap { Second(it) },
+                carrierMergedResetEvents.mapCheap { First(lastMobileEvent.sample()) },
             )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _carrierId.value)
+            .holdState(First(initialState))
+    }
 
-    private val _inflateSignalStrength: MutableStateFlow<Boolean> = MutableStateFlow(false)
-    override val inflateSignalStrength =
-        _inflateSignalStrength
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = "inflate",
-                initialValue = _inflateSignalStrength.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _inflateSignalStrength.value)
-
-    // I don't see a reason why we would turn the config off for demo mode.
-    override val allowNetworkSliceIndicator = MutableStateFlow(true)
-
-    private val _isEmergencyOnly = MutableStateFlow(false)
-    override val isEmergencyOnly =
-        _isEmergencyOnly
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_EMERGENCY,
-                initialValue = _isEmergencyOnly.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _isEmergencyOnly.value)
-
-    private val _isRoaming = MutableStateFlow(false)
-    override val isRoaming =
-        _isRoaming
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_ROAMING,
-                initialValue = _isRoaming.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _isRoaming.value)
-
-    private val _operatorAlphaShort: MutableStateFlow<String?> = MutableStateFlow(null)
-    override val operatorAlphaShort =
-        _operatorAlphaShort
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_OPERATOR,
-                initialValue = _operatorAlphaShort.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _operatorAlphaShort.value)
-
-    private val _isInService = MutableStateFlow(false)
-    override val isInService =
-        _isInService
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_IS_IN_SERVICE,
-                initialValue = _isInService.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _isInService.value)
-
-    private val _isNonTerrestrial = MutableStateFlow(false)
-    override val isNonTerrestrial =
-        _isNonTerrestrial
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_IS_NTN,
-                initialValue = _isNonTerrestrial.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _isNonTerrestrial.value)
-
-    private val _isGsm = MutableStateFlow(false)
-    override val isGsm =
-        _isGsm
-            .logDiffsForTable(tableLogBuffer, columnName = COL_IS_GSM, initialValue = _isGsm.value)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _isGsm.value)
-
-    private val _cdmaLevel = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
-    override val cdmaLevel =
-        _cdmaLevel
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_CDMA_LEVEL,
-                initialValue = _cdmaLevel.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _cdmaLevel.value)
-
-    private val _primaryLevel = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
-    override val primaryLevel =
-        _primaryLevel
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_PRIMARY_LEVEL,
-                initialValue = _primaryLevel.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _primaryLevel.value)
-
-    private val _satelliteLevel = MutableStateFlow(0)
-    override val satelliteLevel: StateFlow<Int> =
-        _satelliteLevel
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_SATELLITE_LEVEL,
-                initialValue = _satelliteLevel.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _satelliteLevel.value)
-
-    private val _dataConnectionState = MutableStateFlow(DataConnectionState.Disconnected)
-    override val dataConnectionState =
-        _dataConnectionState
-            .logDiffsForTable(tableLogBuffer, initialValue = _dataConnectionState.value)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _dataConnectionState.value)
-
-    private val _dataActivityDirection =
-        MutableStateFlow(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
-    override val dataActivityDirection =
-        _dataActivityDirection
-            .logDiffsForTable(tableLogBuffer, initialValue = _dataActivityDirection.value)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _dataActivityDirection.value)
-
-    private val _carrierNetworkChangeActive = MutableStateFlow(false)
-    override val carrierNetworkChangeActive =
-        _carrierNetworkChangeActive
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_CARRIER_NETWORK_CHANGE,
-                initialValue = _carrierNetworkChangeActive.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _carrierNetworkChangeActive.value)
-
-    private val _resolvedNetworkType: MutableStateFlow<ResolvedNetworkType> =
-        MutableStateFlow(ResolvedNetworkType.UnknownNetworkType)
-    override val resolvedNetworkType =
-        _resolvedNetworkType
-            .logDiffsForTable(tableLogBuffer, initialValue = _resolvedNetworkType.value)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _resolvedNetworkType.value)
-
-    override val numberOfLevels =
-        _inflateSignalStrength
-            .map { shouldInflate ->
-                if (shouldInflate) {
-                    DEFAULT_NUM_LEVELS + 1
-                } else {
-                    DEFAULT_NUM_LEVELS
+    override val carrierId: State<Int> =
+        lastEvent
+            .map { it.firstOrNull()?.carrierId ?: INVALID_SUBSCRIPTION_ID }
+            .also {
+                onActivated {
+                    logDiffsForTable(
+                        intState = it,
+                        tableLogBuffer = tableLogBuffer,
+                        columnName = COL_CARRIER_ID,
+                    )
                 }
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
 
-    override val dataEnabled = MutableStateFlow(true)
-
-    override val cdmaRoaming = MutableStateFlow(false)
-
-    override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived(DEMO_CARRIER_NAME))
-
-    override val carrierName =
-        MutableStateFlow(NetworkNameModel.SubscriptionDerived(DEMO_CARRIER_NAME))
-
-    override val isAllowedDuringAirplaneMode = MutableStateFlow(false)
-
-    override val hasPrioritizedNetworkCapabilities = MutableStateFlow(false)
-
-    override suspend fun isInEcmMode(): Boolean = false
-
-    /**
-     * Process a new demo mobile event. Note that [resolvedNetworkType] must be passed in separately
-     * from the event, due to the requirement to reverse the mobile mappings lookup in the top-level
-     * repository.
-     */
-    fun processDemoMobileEvent(
-        event: FakeNetworkEventModel.Mobile,
-        resolvedNetworkType: ResolvedNetworkType,
-    ) {
-        // This is always true here, because we split out disabled states at the data-source level
-        dataEnabled.value = true
-        networkName.value = NetworkNameModel.IntentDerived(event.name)
-        carrierName.value = NetworkNameModel.SubscriptionDerived("${event.name} ${event.subId}")
-
-        _carrierId.value = event.carrierId ?: INVALID_SUBSCRIPTION_ID
-
-        _inflateSignalStrength.value = event.inflateStrength
-
-        cdmaRoaming.value = event.roaming
-        _isRoaming.value = event.roaming
-        // TODO(b/261029387): not yet supported
-        _isEmergencyOnly.value = false
-        _operatorAlphaShort.value = event.name
-        _isInService.value = (event.level ?: 0) > 0
-        // TODO(b/261029387): not yet supported
-        _isGsm.value = false
-        _cdmaLevel.value = event.level ?: 0
-        _primaryLevel.value = event.level ?: 0
-        // TODO(b/261029387): not yet supported
-        _dataConnectionState.value = DataConnectionState.Connected
-        _dataActivityDirection.value =
-            (event.activity ?: TelephonyManager.DATA_ACTIVITY_NONE).toMobileDataActivityModel()
-        _carrierNetworkChangeActive.value = event.carrierNetworkChange
-        _resolvedNetworkType.value = resolvedNetworkType
-        _isNonTerrestrial.value = event.ntn
-
-        isAllowedDuringAirplaneMode.value = false
-        hasPrioritizedNetworkCapabilities.value = event.slice
+    override val inflateSignalStrength: State<Boolean> = buildState {
+        mobileEvents
+            .map { ev -> ev.inflateStrength }
+            .holdState(false)
+            .also { logDiffsForTable(it, tableLogBuffer, "", columnName = "inflate") }
     }
 
-    fun processCarrierMergedEvent(event: FakeWifiEventModel.CarrierMerged) {
-        // This is always true here, because we split out disabled states at the data-source level
-        dataEnabled.value = true
-        networkName.value = NetworkNameModel.IntentDerived(CARRIER_MERGED_NAME)
-        carrierName.value = NetworkNameModel.SubscriptionDerived(CARRIER_MERGED_NAME)
-        // TODO(b/276943904): is carrierId a thing with carrier merged networks?
-        _carrierId.value = INVALID_SUBSCRIPTION_ID
-        cdmaRoaming.value = false
-        _primaryLevel.value = event.level
-        _cdmaLevel.value = event.level
-        _dataActivityDirection.value = event.activity.toMobileDataActivityModel()
+    // I don't see a reason why we would turn the config off for demo mode.
+    override val allowNetworkSliceIndicator: State<Boolean> = stateOf(true)
 
-        // These fields are always the same for carrier-merged networks
-        _resolvedNetworkType.value = ResolvedNetworkType.CarrierMergedNetworkType
-        _dataConnectionState.value = DataConnectionState.Connected
-        _isRoaming.value = false
-        _isEmergencyOnly.value = false
-        _operatorAlphaShort.value = null
-        _isInService.value = true
-        _isGsm.value = false
-        _carrierNetworkChangeActive.value = false
-        isAllowedDuringAirplaneMode.value = true
-        hasPrioritizedNetworkCapabilities.value = false
+    // TODO(b/261029387): not yet supported
+    override val isEmergencyOnly: State<Boolean> = stateOf(false)
+
+    override val isRoaming: State<Boolean> =
+        lastEvent
+            .map { it.firstOrNull()?.roaming ?: false }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_ROAMING) } }
+
+    override val operatorAlphaShort: State<String?> =
+        lastEvent
+            .map { it.firstOrNull()?.name }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_OPERATOR) }
+            }
+
+    override val isInService: State<Boolean> =
+        lastEvent
+            .map {
+                when (it) {
+                    is First -> it.value.level?.let { level -> level > 0 } ?: false
+                    is Second -> true
+                }
+            }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_IS_IN_SERVICE) }
+            }
+
+    override val isNonTerrestrial: State<Boolean> = buildState {
+        mobileEvents
+            .map { it.ntn }
+            .holdState(false)
+            .also { logDiffsForTable(it, tableLogBuffer, columnName = COL_IS_NTN) }
     }
 
+    // TODO(b/261029387): not yet supported
+    override val isGsm: State<Boolean> = stateOf(false)
+
+    override val cdmaLevel: State<Int> =
+        lastEvent
+            .map {
+                when (it) {
+                    is First -> it.value.level ?: 0
+                    is Second -> it.value.level
+                }
+            }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_CDMA_LEVEL) }
+            }
+
+    override val primaryLevel: State<Int> =
+        lastEvent
+            .map {
+                when (it) {
+                    is First -> it.value.level ?: 0
+                    is Second -> it.value.level
+                }
+            }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_PRIMARY_LEVEL) }
+            }
+
+    override val satelliteLevel: State<Int> =
+        stateOf(0).also {
+            onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_SATELLITE_LEVEL) }
+        }
+
+    // TODO(b/261029387): not yet supported
+    override val dataConnectionState: State<DataConnectionState> =
+        buildState {
+                mergeLeft(mobileEvents, wifiEvents)
+                    .map { DataConnectionState.Connected }
+                    .holdState(DataConnectionState.Disconnected)
+            }
+            .also {
+                onActivated {
+                    logDiffsForTable(diffableState = it, tableLogBuffer = tableLogBuffer)
+                }
+            }
+
+    override val dataActivityDirection: State<DataActivityModel> =
+        lastEvent
+            .map {
+                val activity =
+                    when (it) {
+                        is First -> it.value.activity ?: TelephonyManager.DATA_ACTIVITY_NONE
+                        is Second -> it.value.activity
+                    }
+                activity.toMobileDataActivityModel()
+            }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnPrefix = "") } }
+
+    override val carrierNetworkChangeActive: State<Boolean> =
+        lastEvent
+            .map { it.firstOrNull()?.carrierNetworkChange ?: false }
+            .also {
+                onActivated {
+                    logDiffsForTable(it, tableLogBuffer, columnName = COL_CARRIER_NETWORK_CHANGE)
+                }
+            }
+
+    override val resolvedNetworkType: State<ResolvedNetworkType> = buildState {
+        lastEvent
+            .mapTransactionally {
+                it.firstOrNull()?.dataType?.let { resolvedNetworkTypeForIconGroup(it) }
+                    ?: ResolvedNetworkType.CarrierMergedNetworkType
+            }
+            .also { logDiffsForTable(it, tableLogBuffer, columnPrefix = "") }
+    }
+
+    override val numberOfLevels: State<Int> =
+        inflateSignalStrength.map { shouldInflate ->
+            if (shouldInflate) DEFAULT_NUM_LEVELS + 1 else DEFAULT_NUM_LEVELS
+        }
+
+    override val dataEnabled: State<Boolean> = stateOf(true)
+
+    override val cdmaRoaming: State<Boolean> = lastEvent.map { it.firstOrNull()?.roaming ?: false }
+
+    override val networkName: State<NetworkNameModel.IntentDerived> =
+        lastEvent.map {
+            NetworkNameModel.IntentDerived(it.firstOrNull()?.name ?: CARRIER_MERGED_NAME)
+        }
+
+    override val carrierName: State<NetworkNameModel.SubscriptionDerived> =
+        lastEvent.map {
+            NetworkNameModel.SubscriptionDerived(
+                it.firstOrNull()?.let { event -> "${event.name} ${event.subId}" }
+                    ?: CARRIER_MERGED_NAME
+            )
+        }
+
+    override val isAllowedDuringAirplaneMode: State<Boolean> = lastEvent.map { it is Second }
+
+    override val hasPrioritizedNetworkCapabilities: State<Boolean> =
+        lastEvent.map { it.firstOrNull()?.slice ?: false }
+
+    override val isInEcmMode: State<Boolean> = stateOf(false)
+
+    private fun TransactionScope.resolvedNetworkTypeForIconGroup(
+        iconGroup: SignalIcon.MobileIconGroup?
+    ) = DefaultNetworkType(mobileMappingsReverseLookup.sample()[iconGroup] ?: "dis")
+
     companion object {
         private const val DEMO_CARRIER_NAME = "Demo Carrier"
         private const val CARRIER_MERGED_NAME = "Carrier Merged Network"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairos.kt
index dee59bd..925ee54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,17 +20,35 @@
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
 import android.util.Log
-import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.settingslib.SignalIcon
 import com.android.settingslib.mobile.MobileMappings
 import com.android.settingslib.mobile.TelephonyIcons
-import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.KairosBuilder
+import com.android.systemui.activated
+import com.android.systemui.kairos.BuildScope
+import com.android.systemui.kairos.Events
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.GroupedEvents
+import com.android.systemui.kairos.Incremental
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.TransactionScope
+import com.android.systemui.kairos.asIncremental
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.emptyEvents
+import com.android.systemui.kairos.filter
+import com.android.systemui.kairos.filterIsInstance
+import com.android.systemui.kairos.groupBy
+import com.android.systemui.kairos.groupByKey
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapCheap
+import com.android.systemui.kairos.mapNotNull
+import com.android.systemui.kairos.mapValues
+import com.android.systemui.kairos.mergeLeft
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.TableLogBufferFactory
-import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
-import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepositoryKairos
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile
@@ -38,111 +56,149 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.MOBILE_CONNECTION_BUFFER_SIZE
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.flow.stateIn
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
 
 /** This repository vends out data based on demo mode commands */
+@ExperimentalKairosApi
 class DemoMobileConnectionsRepositoryKairos
-@Inject
+@AssistedInject
 constructor(
-    private val mobileDataSource: DemoModeMobileConnectionDataSource,
+    mobileDataSource: DemoModeMobileConnectionDataSourceKairos,
     private val wifiDataSource: DemoModeWifiDataSource,
-    @Background private val scope: CoroutineScope,
     context: Context,
     private val logFactory: TableLogBufferFactory,
-) : MobileConnectionsRepository, MobileConnectionsRepositoryKairos {
+) : MobileConnectionsRepositoryKairos, KairosBuilder by kairosBuilder() {
 
-    private var mobileDemoCommandJob: Job? = null
-    private var wifiDemoCommandJob: Job? = null
-
-    private var carrierMergedSubId: Int? = null
-
-    private var connectionRepoCache = mutableMapOf<Int, CacheContainer>()
-    private val subscriptionInfoCache = mutableMapOf<Int, SubscriptionModel>()
-    val demoModeFinishedEvent = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
-
-    private val _subscriptions = MutableStateFlow<List<SubscriptionModel>>(listOf())
-    override val subscriptions =
-        _subscriptions
-            .onEach { infos -> dropUnusedReposFromCache(infos) }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), _subscriptions.value)
-
-    private fun dropUnusedReposFromCache(newInfos: List<SubscriptionModel>) {
-        // Remove any connection repository from the cache that isn't in the new set of IDs. They
-        // will get garbage collected once their subscribers go away
-        val currentValidSubscriptionIds = newInfos.map { it.subscriptionId }
-
-        connectionRepoCache =
-            connectionRepoCache
-                .filter { currentValidSubscriptionIds.contains(it.key) }
-                .toMutableMap()
+    @AssistedFactory
+    fun interface Factory {
+        fun create(): DemoMobileConnectionsRepositoryKairos
     }
 
-    private fun maybeCreateSubscription(subId: Int) {
-        if (!subscriptionInfoCache.containsKey(subId)) {
-            SubscriptionModel(
+    private val wifiEvents: Events<FakeWifiEventModel?> = buildEvents {
+        wifiDataSource.wifiEvents.toEvents()
+    }
+
+    private val mobileEventsWithSubId: Events<Pair<Int, FakeNetworkEventModel>> =
+        mobileDataSource.mobileEvents.mapNotNull { event ->
+            event?.let { (event.subId ?: lastSeenSubId.sample())?.let { it to event } }
+        }
+
+    private val mobileEventsBySubId: GroupedEvents<Int, FakeNetworkEventModel> =
+        mobileEventsWithSubId.map { mapOf(it) }.groupByKey()
+
+    private val carrierMergedEvents: Events<FakeWifiEventModel.CarrierMerged> =
+        wifiEvents.filterIsInstance<FakeWifiEventModel.CarrierMerged>()
+
+    private val wifiEventsBySubId: GroupedEvents<Int, FakeWifiEventModel.CarrierMerged> =
+        carrierMergedEvents.groupBy { it.subscriptionId }
+
+    private val lastSeenSubId: State<Int?> = buildState {
+        mergeLeft(
+                mobileEventsWithSubId.mapCheap { it.first },
+                carrierMergedEvents.mapCheap { it.subscriptionId },
+            )
+            .holdState(null)
+    }
+
+    private val activeCarrierMergedSubscription: State<Int?> = buildState {
+        mergeLeft(
+                carrierMergedEvents.mapCheap { it.subscriptionId },
+                wifiEvents
+                    .filter {
+                        it is FakeWifiEventModel.Wifi || it is FakeWifiEventModel.WifiDisabled
+                    }
+                    .map { null },
+            )
+            .holdState(null)
+    }
+
+    private val activeMobileSubscriptions: State<Set<Int>> = buildState {
+        mobileDataSource.mobileEvents
+            .mapNotNull { event ->
+                when (event) {
+                    null -> null
+                    is Mobile -> event.subId?.let { subId -> { subs: Set<Int> -> subs + subId } }
+                    is MobileDisabled ->
+                        (event.subId ?: maybeGetOnlySubIdForRemoval())?.let { subId ->
+                            { subs: Set<Int> -> subs - subId }
+                        }
+                }
+            }
+            .foldState(emptySet()) { f, s -> f(s) }
+    }
+
+    private val subscriptionIds: State<Set<Int>> =
+        combine(activeMobileSubscriptions, activeCarrierMergedSubscription) { mobile, carrierMerged
+            ->
+            carrierMerged?.let { mobile + carrierMerged } ?: mobile
+        }
+
+    private val subscriptionsById: State<Map<Int, SubscriptionModel>> =
+        subscriptionIds.map { subs ->
+            subs.associateWith { subId ->
+                SubscriptionModel(
                     subscriptionId = subId,
                     isOpportunistic = false,
                     carrierName = DEFAULT_CARRIER_NAME,
                     profileClass = PROFILE_CLASS_UNSET,
                 )
-                .also { subscriptionInfoCache[subId] = it }
+            }
+        }
 
-            _subscriptions.value = subscriptionInfoCache.values.toList()
+    override val subscriptions: State<Collection<SubscriptionModel>> =
+        subscriptionsById.map { it.values }
+
+    private fun TransactionScope.maybeGetOnlySubIdForRemoval(): Int? {
+        val subIds = activeMobileSubscriptions.sample()
+        return if (subIds.size == 1) {
+            subIds.first()
+        } else {
+            Log.d(
+                TAG,
+                "processDisabledMobileState: Unable to infer subscription to " +
+                    "disable. Specify subId using '-e slot <subId>'. " +
+                    "Known subIds: [${subIds.joinToString(",")}]",
+            )
+            null
         }
     }
 
-    // TODO(b/261029387): add a command for this value
-    override val activeMobileDataSubscriptionId =
-        subscriptions
-            .mapLatest { infos ->
-                // For now, active is just the first in the list
-                infos.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID
-            }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                subscriptions.value.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID,
-            )
+    private val reposBySubId: Incremental<Int, DemoMobileConnectionRepositoryKairos> =
+        buildIncremental {
+            subscriptionsById
+                .asIncremental()
+                .mapValues { (id, _) -> buildSpec { newRepo(id) } }
+                .applyLatestSpecForKey()
+        }
 
-    override val activeMobileDataRepository: StateFlow<MobileConnectionRepository?> =
-        activeMobileDataSubscriptionId
-            .map { getRepoForSubId(it) }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                getRepoForSubId(activeMobileDataSubscriptionId.value),
-            )
+    // TODO(b/261029387): add a command for this value
+    override val activeMobileDataSubscriptionId: State<Int> =
+        // For now, active is just the first in the list
+        subscriptions.map { infos ->
+            infos.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID
+        }
+
+    override val activeMobileDataRepository: State<DemoMobileConnectionRepositoryKairos?> =
+        combine(activeMobileDataSubscriptionId, reposBySubId) { subId, repoMap -> repoMap[subId] }
 
     // TODO(b/261029387): consider adding a demo command for this
-    override val activeSubChangedInGroupEvent: Flow<Unit> = flowOf()
+    override val activeSubChangedInGroupEvent: Events<Unit> = emptyEvents
 
     /** Demo mode doesn't currently support modifications to the mobile mappings */
-    override val defaultDataSubRatConfig =
-        MutableStateFlow(MobileMappings.Config.readConfig(context))
+    override val defaultDataSubRatConfig: State<MobileMappings.Config> =
+        stateOf(MobileMappings.Config.readConfig(context))
 
-    override val defaultMobileIconGroup = flowOf(TelephonyIcons.THREE_G)
+    override val defaultMobileIconGroup: State<SignalIcon.MobileIconGroup> =
+        stateOf(TelephonyIcons.THREE_G)
 
     // TODO(b/339023069): demo command for device-based emergency calls state
-    override val isDeviceEmergencyCallCapable: StateFlow<Boolean> = MutableStateFlow(false)
+    override val isDeviceEmergencyCallCapable: State<Boolean> = stateOf(false)
 
-    override val isAnySimSecure: Flow<Boolean> = flowOf(getIsAnySimSecure())
+    override val isAnySimSecure: State<Boolean> = stateOf(false)
 
-    override fun getIsAnySimSecure(): Boolean = false
-
-    override val defaultMobileIconMapping = MutableStateFlow(TelephonyIcons.ICON_NAME_TO_ICON)
+    override val defaultMobileIconMapping: State<Map<String, SignalIcon.MobileIconGroup>> =
+        stateOf(TelephonyIcons.ICON_NAME_TO_ICON)
 
     /**
      * In order to maintain compatibility with the old demo mode shell command API, reverse the
@@ -153,185 +209,47 @@
      * Note: collisions don't matter here, because the data source (the command line) only cares
      * about the resulting icon, not the underlying network type.
      */
-    private val mobileMappingsReverseLookup: StateFlow<Map<SignalIcon.MobileIconGroup, String>> =
-        defaultMobileIconMapping
-            .mapLatest { networkToIconMap -> networkToIconMap.reverse() }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                defaultMobileIconMapping.value.reverse(),
-            )
+    private val mobileMappingsReverseLookup: State<Map<SignalIcon.MobileIconGroup, String>> =
+        defaultMobileIconMapping.map { networkToIconMap -> networkToIconMap.reverse() }
 
-    private fun <K, V> Map<K, V>.reverse() = entries.associateBy({ it.value }) { it.key }
+    private fun <K, V> Map<K, V>.reverse() = entries.associate { (k, v) -> v to k }
 
     // TODO(b/261029387): add a command for this value
-    override val defaultDataSubId: MutableStateFlow<Int?> = MutableStateFlow(null)
+    override val defaultDataSubId: State<Int?> = stateOf(null)
 
     // TODO(b/261029387): not yet supported
-    override val mobileIsDefault: StateFlow<Boolean> = MutableStateFlow(true)
+    override val mobileIsDefault: State<Boolean> = stateOf(true)
 
     // TODO(b/261029387): not yet supported
-    override val hasCarrierMergedConnection = MutableStateFlow(false)
+    override val hasCarrierMergedConnection: State<Boolean> = stateOf(false)
 
     // TODO(b/261029387): not yet supported
-    override val defaultConnectionIsValidated: StateFlow<Boolean> = MutableStateFlow(true)
+    override val defaultConnectionIsValidated: State<Boolean> = stateOf(true)
 
-    override fun getRepoForSubId(subId: Int): DemoMobileConnectionRepository {
-        val current = connectionRepoCache[subId]?.repo
-        if (current != null) {
-            return current
-        }
+    override val isInEcmMode: State<Boolean> = stateOf(false)
 
-        val new = createDemoMobileConnectionRepo(subId)
-        connectionRepoCache[subId] = new
-        return new.repo
-    }
+    override val mobileConnectionsBySubId: Incremental<Int, DemoMobileConnectionRepositoryKairos>
+        get() = reposBySubId
 
-    private fun createDemoMobileConnectionRepo(subId: Int): CacheContainer {
-        val tableLogBuffer =
-            logFactory.getOrCreate("DemoMobileConnectionLog[$subId]", MOBILE_CONNECTION_BUFFER_SIZE)
-
-        val repo = DemoMobileConnectionRepository(subId, tableLogBuffer, scope)
-        return CacheContainer(repo, lastMobileState = null)
-    }
-
-    fun startProcessingCommands() {
-        mobileDemoCommandJob =
-            scope.launch {
-                mobileDataSource.mobileEvents.filterNotNull().collect { event ->
-                    processMobileEvent(event)
-                }
-            }
-        wifiDemoCommandJob =
-            scope.launch {
-                wifiDataSource.wifiEvents.filterNotNull().collect { event ->
-                    processWifiEvent(event)
-                }
-            }
-    }
-
-    fun stopProcessingCommands() {
-        mobileDemoCommandJob?.cancel()
-        wifiDemoCommandJob?.cancel()
-        _subscriptions.value = listOf()
-        connectionRepoCache.clear()
-        subscriptionInfoCache.clear()
-    }
-
-    override suspend fun isInEcmMode(): Boolean = false
-
-    private fun processMobileEvent(event: FakeNetworkEventModel) {
-        when (event) {
-            is Mobile -> {
-                processEnabledMobileState(event)
-            }
-            is MobileDisabled -> {
-                maybeRemoveSubscription(event.subId)
-            }
-        }
-    }
-
-    private fun processWifiEvent(event: FakeWifiEventModel) {
-        when (event) {
-            is FakeWifiEventModel.WifiDisabled -> disableCarrierMerged()
-            is FakeWifiEventModel.Wifi -> disableCarrierMerged()
-            is FakeWifiEventModel.CarrierMerged -> processCarrierMergedWifiState(event)
-        }
-    }
-
-    private fun processEnabledMobileState(event: Mobile) {
-        // get or create the connection repo, and set its values
-        val subId = event.subId ?: DEFAULT_SUB_ID
-        maybeCreateSubscription(subId)
-
-        val connection = getRepoForSubId(subId)
-        connectionRepoCache[subId]?.lastMobileState = event
-
-        // TODO(b/261029387): until we have a command, use the most recent subId
-        defaultDataSubId.value = subId
-
-        connection.processDemoMobileEvent(event, event.dataType.toResolvedNetworkType())
-    }
-
-    private fun processCarrierMergedWifiState(event: FakeWifiEventModel.CarrierMerged) {
-        // The new carrier merged connection is for a different sub ID, so disable carrier merged
-        // for the current (now old) sub
-        if (carrierMergedSubId != event.subscriptionId) {
-            disableCarrierMerged()
-        }
-
-        // get or create the connection repo, and set its values
-        val subId = event.subscriptionId
-        maybeCreateSubscription(subId)
-        carrierMergedSubId = subId
-
-        // TODO(b/261029387): until we have a command, use the most recent subId
-        defaultDataSubId.value = subId
-
-        val connection = getRepoForSubId(subId)
-        connection.processCarrierMergedEvent(event)
-    }
-
-    private fun maybeRemoveSubscription(subId: Int?) {
-        if (_subscriptions.value.isEmpty()) {
-            // Nothing to do here
-            return
-        }
-
-        val finalSubId =
-            subId
-                ?: run {
-                    // For sake of usability, we can allow for no subId arg if there is only one
-                    // subscription
-                    if (_subscriptions.value.size > 1) {
-                        Log.d(
-                            TAG,
-                            "processDisabledMobileState: Unable to infer subscription to " +
-                                "disable. Specify subId using '-e slot <subId>'" +
-                                "Known subIds: [${subIdsString()}]",
-                        )
-                        return
-                    }
-
-                    // Use the only existing subscription as our arg, since there is only one
-                    _subscriptions.value[0].subscriptionId
-                }
-
-        removeSubscription(finalSubId)
-    }
-
-    private fun disableCarrierMerged() {
-        val currentCarrierMergedSubId = carrierMergedSubId ?: return
-
-        // If this sub ID was previously not carrier merged, we should reset it to its previous
-        // connection.
-        val lastMobileState = connectionRepoCache[carrierMergedSubId]?.lastMobileState
-        if (lastMobileState != null) {
-            processEnabledMobileState(lastMobileState)
-        } else {
-            // Otherwise, just remove the subscription entirely
-            removeSubscription(currentCarrierMergedSubId)
-        }
-    }
-
-    private fun removeSubscription(subId: Int) {
-        val currentSubscriptions = _subscriptions.value
-        subscriptionInfoCache.remove(subId)
-        _subscriptions.value = currentSubscriptions.filter { it.subscriptionId != subId }
-    }
-
-    private fun subIdsString(): String =
-        _subscriptions.value.joinToString(",") { it.subscriptionId.toString() }
-
-    private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType {
-        val key = mobileMappingsReverseLookup.value[this] ?: "dis"
-        return DefaultNetworkType(key)
+    private fun BuildScope.newRepo(subId: Int) = activated {
+        DemoMobileConnectionRepositoryKairos(
+            subId = subId,
+            tableLogBuffer =
+                logFactory.getOrCreate(
+                    "DemoMobileConnectionLog[$subId]",
+                    MOBILE_CONNECTION_BUFFER_SIZE,
+                ),
+            mobileEvents = mobileEventsBySubId[subId].filterIsInstance(),
+            carrierMergedResetEvents =
+                wifiEvents.mapNotNull { it?.takeIf { it !is FakeWifiEventModel.CarrierMerged } },
+            wifiEvents = wifiEventsBySubId[subId],
+            mobileMappingsReverseLookup = mobileMappingsReverseLookup,
+        )
     }
 
     companion object {
         private const val TAG = "DemoMobileConnectionsRepo"
 
-        private const val DEFAULT_SUB_ID = 1
         private const val DEFAULT_CARRIER_NAME = "demo carrier"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSourceKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSourceKairos.kt
index b379384..f329383 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSourceKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoModeMobileConnectionDataSourceKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,33 +24,51 @@
 import android.telephony.TelephonyManager.DATA_ACTIVITY_OUT
 import com.android.settingslib.SignalIcon.MobileIconGroup
 import com.android.settingslib.mobile.TelephonyIcons
+import com.android.systemui.Flags
+import com.android.systemui.KairosActivatable
+import com.android.systemui.KairosBuilder
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.demomode.DemoMode.COMMAND_NETWORK
 import com.android.systemui.demomode.DemoModeController
+import com.android.systemui.kairos.Events
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairosBuilder
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.MobileDisabled
+import dagger.Binds
+import dagger.Provides
+import dagger.multibindings.ElementsIntoSet
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
+import javax.inject.Provider
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.shareIn
 
 /**
  * Data source that can map from demo mode commands to inputs into the
- * [DemoMobileConnectionsRepository]'s flows
+ * [DemoMobileConnectionsRepositoryKairos]
  */
+@ExperimentalKairosApi
+interface DemoModeMobileConnectionDataSourceKairos {
+    val mobileEvents: Events<FakeNetworkEventModel?>
+}
+
+@ExperimentalKairosApi
 @SysUISingleton
-class DemoModeMobileConnectionDataSourceKairos
+class DemoModeMobileConnectionDataSourceKairosImpl
 @Inject
-constructor(demoModeController: DemoModeController, @Background scope: CoroutineScope) {
-    private val demoCommandStream = demoModeController.demoFlowForCommand(COMMAND_NETWORK)
+constructor(demoModeController: DemoModeController) :
+    KairosBuilder by kairosBuilder(), DemoModeMobileConnectionDataSourceKairos {
+    private val demoCommandStream: Flow<Bundle> =
+        demoModeController.demoFlowForCommand(COMMAND_NETWORK)
 
     // If the args contains "mobile", then all of the args are relevant. It's just the way demo mode
     // commands work and it's a little silly
-    private val _mobileCommands = demoCommandStream.map { args -> args.toMobileEvent() }
-    val mobileEvents = _mobileCommands.shareIn(scope, SharingStarted.WhileSubscribed())
+    private val _mobileCommands: Flow<FakeNetworkEventModel?> =
+        demoCommandStream.map { args -> args.toMobileEvent() }
+    override val mobileEvents: Events<FakeNetworkEventModel?> = buildEvents {
+        _mobileCommands.toEvents()
+    }
 
     private fun Bundle.toMobileEvent(): FakeNetworkEventModel? {
         val mobile = getString("mobile") ?: return null
@@ -90,6 +108,23 @@
             ntn = ntn,
         )
     }
+
+    @dagger.Module
+    interface Module {
+        @Binds
+        fun bindImpl(
+            impl: DemoModeMobileConnectionDataSourceKairosImpl
+        ): DemoModeMobileConnectionDataSourceKairos
+
+        companion object {
+            @Provides
+            @ElementsIntoSet
+            fun kairosActivatable(
+                impl: Provider<DemoModeMobileConnectionDataSourceKairosImpl>
+            ): Set<@JvmSuppressWildcards KairosActivatable> =
+                if (Flags.statusBarMobileIconKairos()) setOf(impl.get()) else emptySet()
+        }
+    }
 }
 
 private fun String.toDataType(): MobileIconGroup =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt
index 42171d0..54162bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/model/FakeNetworkEventModel.kt
@@ -25,11 +25,13 @@
  * Nullable fields represent optional command line arguments
  */
 sealed interface FakeNetworkEventModel {
+    // Null means the default (chosen by the repository)
+    val subId: Int?
+
     data class Mobile(
         val level: Int?,
         val dataType: SignalIcon.MobileIconGroup?,
-        // Null means the default (chosen by the repository)
-        val subId: Int?,
+        override val subId: Int?,
         val carrierId: Int?,
         val inflateStrength: Boolean = false,
         @DataActivityType val activity: Int?,
@@ -40,8 +42,5 @@
         val ntn: Boolean = false,
     ) : FakeNetworkEventModel
 
-    data class MobileDisabled(
-        // Null means the default (chosen by the repository)
-        val subId: Int?
-    ) : FakeNetworkEventModel
+    data class MobileDisabled(override val subId: Int?) : FakeNetworkEventModel
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairos.kt
index 4d80efc..d61d11b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,29 +20,24 @@
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import android.telephony.TelephonyManager
 import android.util.Log
+import com.android.systemui.KairosBuilder
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos.Companion.DEFAULT_NUM_LEVELS
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
 import javax.inject.Inject
-import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.withContext
 
 /**
  * A repository implementation for a carrier merged (aka VCN) network. A carrier merged network is
@@ -54,33 +49,40 @@
  * See [MobileConnectionRepositoryImpl] for a repository implementation of a typical mobile
  * connection.
  */
+@ExperimentalKairosApi
 class CarrierMergedConnectionRepositoryKairos(
     override val subId: Int,
     override val tableLogBuffer: TableLogBuffer,
     private val telephonyManager: TelephonyManager,
-    private val bgContext: CoroutineContext,
-    @Background private val scope: CoroutineScope,
     val wifiRepository: WifiRepository,
-) : MobileConnectionRepository, MobileConnectionRepositoryKairos {
+    override val isInEcmMode: State<Boolean>,
+) : MobileConnectionRepositoryKairos, KairosBuilder by kairosBuilder() {
     init {
         if (telephonyManager.subscriptionId != subId) {
-            throw IllegalStateException(
-                "CarrierMergedRepo: TelephonyManager should be created with subId($subId). " +
-                    "Found ${telephonyManager.subscriptionId} instead."
+            error(
+                """CarrierMergedRepo: TelephonyManager should be created with subId($subId).
+                    | Found ${telephonyManager.subscriptionId} instead."""
+                    .trimMargin()
             )
         }
     }
 
+    private val isWifiEnabled: State<Boolean> = buildState {
+        wifiRepository.isWifiEnabled.toState()
+    }
+    private val isWifiDefault: State<Boolean> = buildState {
+        wifiRepository.isWifiDefault.toState()
+    }
+    private val wifiNetwork: State<WifiNetworkModel> = buildState {
+        wifiRepository.wifiNetwork.toState()
+    }
+
     /**
      * Outputs the carrier merged network to use, or null if we don't have a valid carrier merged
      * network.
      */
-    private val network: Flow<WifiNetworkModel.CarrierMerged?> =
-        combine(
-            wifiRepository.isWifiEnabled,
-            wifiRepository.isWifiDefault,
-            wifiRepository.wifiNetwork,
-        ) { isEnabled, isDefault, network ->
+    private val network: State<WifiNetworkModel.CarrierMerged?> =
+        combine(isWifiEnabled, isWifiDefault, wifiNetwork) { isEnabled, isDefault, network ->
             when {
                 !isEnabled -> null
                 !isDefault -> null
@@ -88,9 +90,9 @@
                 network.subscriptionId != subId -> {
                     Log.w(
                         TAG,
-                        "Connection repo subId=$subId " +
-                            "does not equal wifi repo subId=${network.subscriptionId}; " +
-                            "not showing carrier merged",
+                        """Connection repo subId=$subId does not equal wifi repo
+                            | subId=${network.subscriptionId}; not showing carrier merged"""
+                            .trimMargin(),
                     )
                     null
                 }
@@ -98,101 +100,82 @@
             }
         }
 
-    override val cdmaRoaming: StateFlow<Boolean> = MutableStateFlow(ROAMING).asStateFlow()
+    override val cdmaRoaming: State<Boolean> = stateOf(ROAMING)
 
-    override val networkName: StateFlow<NetworkNameModel> =
-        network
-            // The SIM operator name should be the same throughout the lifetime of a subId, **but**
-            // it may not be available when this repo is created because it takes time to load. To
-            // be safe, we re-fetch it each time the network has changed.
-            .map { NetworkNameModel.SimDerived(telephonyManager.simOperatorName) }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                NetworkNameModel.SimDerived(telephonyManager.simOperatorName),
-            )
+    override val networkName: State<NetworkNameModel> =
+        // The SIM operator name should be the same throughout the lifetime of a subId, **but**
+        // it may not be available when this repo is created because it takes time to load. To
+        // be safe, we re-fetch it each time the network has changed.
+        network.map { NetworkNameModel.SimDerived(telephonyManager.simOperatorName) }
 
-    override val carrierName: StateFlow<NetworkNameModel> = networkName
+    override val carrierName: State<NetworkNameModel>
+        get() = networkName
 
-    override val numberOfLevels: StateFlow<Int> =
-        wifiRepository.wifiNetwork
-            .map {
-                if (it is WifiNetworkModel.CarrierMerged) {
-                    it.numberOfLevels
-                } else {
-                    DEFAULT_NUM_LEVELS
-                }
+    override val numberOfLevels: State<Int> =
+        wifiNetwork.map {
+            if (it is WifiNetworkModel.CarrierMerged) {
+                it.numberOfLevels
+            } else {
+                DEFAULT_NUM_LEVELS
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
+        }
 
-    override val primaryLevel =
-        network
-            .map { it?.level ?: SIGNAL_STRENGTH_NONE_OR_UNKNOWN }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
+    override val primaryLevel: State<Int> =
+        network.map { it?.level ?: SIGNAL_STRENGTH_NONE_OR_UNKNOWN }
 
-    override val cdmaLevel =
-        network
-            .map { it?.level ?: SIGNAL_STRENGTH_NONE_OR_UNKNOWN }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
+    override val cdmaLevel: State<Int> =
+        network.map { it?.level ?: SIGNAL_STRENGTH_NONE_OR_UNKNOWN }
 
-    override val dataActivityDirection = wifiRepository.wifiActivity
+    override val dataActivityDirection: State<DataActivityModel> = buildState {
+        wifiRepository.wifiActivity.toState()
+    }
 
-    override val resolvedNetworkType =
-        network
-            .map {
-                if (it != null) {
-                    ResolvedNetworkType.CarrierMergedNetworkType
-                } else {
-                    ResolvedNetworkType.UnknownNetworkType
-                }
+    override val resolvedNetworkType: State<ResolvedNetworkType> =
+        network.map {
+            if (it != null) {
+                ResolvedNetworkType.CarrierMergedNetworkType
+            } else {
+                ResolvedNetworkType.UnknownNetworkType
             }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                ResolvedNetworkType.UnknownNetworkType,
-            )
+        }
 
-    override val dataConnectionState =
-        network
-            .map {
-                if (it != null) {
-                    DataConnectionState.Connected
-                } else {
-                    DataConnectionState.Disconnected
-                }
+    override val dataConnectionState: State<DataConnectionState> =
+        network.map {
+            if (it != null) {
+                DataConnectionState.Connected
+            } else {
+                DataConnectionState.Disconnected
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), DataConnectionState.Disconnected)
+        }
 
-    override val isRoaming = MutableStateFlow(false).asStateFlow()
-    override val carrierId = MutableStateFlow(INVALID_SUBSCRIPTION_ID).asStateFlow()
-    override val inflateSignalStrength = MutableStateFlow(false).asStateFlow()
-    override val allowNetworkSliceIndicator = MutableStateFlow(false).asStateFlow()
-    override val isEmergencyOnly = MutableStateFlow(false).asStateFlow()
-    override val operatorAlphaShort = MutableStateFlow(null).asStateFlow()
-    override val isInService = MutableStateFlow(true).asStateFlow()
-    override val isNonTerrestrial = MutableStateFlow(false).asStateFlow()
-    override val isGsm = MutableStateFlow(false).asStateFlow()
-    override val carrierNetworkChangeActive = MutableStateFlow(false).asStateFlow()
-    override val satelliteLevel = MutableStateFlow(0)
+    override val isRoaming: State<Boolean> = stateOf(false)
+    override val carrierId: State<Int> = stateOf(INVALID_SUBSCRIPTION_ID)
+    override val inflateSignalStrength: State<Boolean> = stateOf(false)
+    override val allowNetworkSliceIndicator: State<Boolean> = stateOf(false)
+    override val isEmergencyOnly: State<Boolean> = stateOf(false)
+    override val operatorAlphaShort: State<String?> = stateOf(null)
+    override val isInService: State<Boolean> = stateOf(true)
+    override val isNonTerrestrial: State<Boolean> = stateOf(false)
+    override val isGsm: State<Boolean> = stateOf(false)
+    override val carrierNetworkChangeActive: State<Boolean> = stateOf(false)
+    override val satelliteLevel: State<Int> = stateOf(0)
 
     /**
      * Carrier merged connections happen over wifi but are displayed as a mobile triangle. Because
      * they occur over wifi, it's possible to have a valid carrier merged connection even during
      * airplane mode. See b/291993542.
      */
-    override val isAllowedDuringAirplaneMode = MutableStateFlow(true).asStateFlow()
+    override val isAllowedDuringAirplaneMode: State<Boolean> = stateOf(true)
 
     /**
      * It's not currently considered possible that a carrier merged network can have these
      * prioritized capabilities. If we need to track them, we can add the same check as is in
      * [MobileConnectionRepositoryImpl].
      */
-    override val hasPrioritizedNetworkCapabilities = MutableStateFlow(false).asStateFlow()
+    override val hasPrioritizedNetworkCapabilities: State<Boolean> = stateOf(false)
 
-    override val dataEnabled: StateFlow<Boolean> = wifiRepository.isWifiEnabled
-
-    override suspend fun isInEcmMode(): Boolean =
-        withContext(bgContext) { telephonyManager.emergencyCallbackMode }
+    override val dataEnabled: State<Boolean>
+        get() = isWifiEnabled
 
     companion object {
         // Carrier merged is never roaming
@@ -204,18 +187,19 @@
     @Inject
     constructor(
         private val telephonyManager: TelephonyManager,
-        @Background private val bgContext: CoroutineContext,
-        @Background private val scope: CoroutineScope,
         private val wifiRepository: WifiRepository,
     ) {
-        fun build(subId: Int, mobileLogger: TableLogBuffer): MobileConnectionRepository {
-            return CarrierMergedConnectionRepository(
+        fun build(
+            subId: Int,
+            mobileLogger: TableLogBuffer,
+            mobileRepo: MobileConnectionRepositoryKairos,
+        ): CarrierMergedConnectionRepositoryKairos {
+            return CarrierMergedConnectionRepositoryKairos(
                 subId,
                 mobileLogger,
                 telephonyManager.createForSubscriptionId(subId),
-                bgContext,
-                scope,
                 wifiRepository,
+                mobileRepo.isInEcmMode,
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt
index 38e6216..1a8ca95 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,24 +18,23 @@
 
 import android.util.IndentingPrintWriter
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.KairosBuilder
+import com.android.systemui.kairos.BuildSpec
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.flatMap
+import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
-import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
 import java.io.PrintWriter
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.stateIn
 
 /**
  * A repository that fully implements a mobile connection.
@@ -43,383 +42,200 @@
  * This connection could either be a typical mobile connection (see [MobileConnectionRepositoryImpl]
  * or a carrier merged connection (see [CarrierMergedConnectionRepository]). This repository
  * switches between the two types of connections based on whether the connection is currently
- * carrier merged (see [setIsCarrierMerged]).
+ * carrier merged.
  */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-class FullMobileConnectionRepositoryKairos(
-    override val subId: Int,
-    startingIsCarrierMerged: Boolean,
-    override val tableLogBuffer: TableLogBuffer,
-    subscriptionModel: Flow<SubscriptionModel?>,
-    private val defaultNetworkName: NetworkNameModel,
-    private val networkNameSeparator: String,
-    @Background scope: CoroutineScope,
-    private val mobileRepoFactory: MobileConnectionRepositoryImpl.Factory,
-    private val carrierMergedRepoFactory: CarrierMergedConnectionRepository.Factory,
-) : MobileConnectionRepository, MobileConnectionRepositoryKairos {
-    /**
-     * Sets whether this connection is a typical mobile connection or a carrier merged connection.
-     */
-    fun setIsCarrierMerged(isCarrierMerged: Boolean) {
-        _isCarrierMerged.value = isCarrierMerged
-    }
+@ExperimentalKairosApi
+class FullMobileConnectionRepositoryKairos
+@AssistedInject
+constructor(
+    @Assisted override val subId: Int,
+    @Assisted override val tableLogBuffer: TableLogBuffer,
+    @Assisted private val mobileRepo: MobileConnectionRepositoryKairos,
+    @Assisted private val carrierMergedRepoSpec: BuildSpec<MobileConnectionRepositoryKairos>,
+    @Assisted private val isCarrierMerged: State<Boolean>,
+) : MobileConnectionRepositoryKairos, KairosBuilder by kairosBuilder() {
 
-    /**
-     * Returns true if this repo is currently for a carrier merged connection and false otherwise.
-     */
-    @VisibleForTesting fun getIsCarrierMerged() = _isCarrierMerged.value
-
-    private val _isCarrierMerged = MutableStateFlow(startingIsCarrierMerged)
-    private val isCarrierMerged: StateFlow<Boolean> =
-        _isCarrierMerged
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = "isCarrierMerged",
-                initialValue = startingIsCarrierMerged,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), startingIsCarrierMerged)
-
-    private val mobileRepo: MobileConnectionRepository by lazy {
-        mobileRepoFactory.build(
-            subId,
-            tableLogBuffer,
-            subscriptionModel,
-            defaultNetworkName,
-            networkNameSeparator,
-        )
-    }
-
-    private val carrierMergedRepo: MobileConnectionRepository by lazy {
-        carrierMergedRepoFactory.build(subId, tableLogBuffer)
+    init {
+        onActivated {
+            logDiffsForTable(isCarrierMerged, tableLogBuffer, columnName = "isCarrierMerged")
+        }
     }
 
     @VisibleForTesting
-    val activeRepo: StateFlow<MobileConnectionRepository> = run {
-        val initial =
-            if (startingIsCarrierMerged) {
-                carrierMergedRepo
+    val activeRepo: State<MobileConnectionRepositoryKairos> = buildState {
+        isCarrierMerged.mapLatestBuild { merged ->
+            if (merged) {
+                carrierMergedRepoSpec.applySpec()
             } else {
                 mobileRepo
             }
-
-        this.isCarrierMerged
-            .mapLatest { isCarrierMerged ->
-                if (isCarrierMerged) {
-                    carrierMergedRepo
-                } else {
-                    mobileRepo
-                }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), initial)
+        }
     }
 
-    override val carrierId =
-        activeRepo
-            .flatMapLatest { it.carrierId }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.carrierId.value)
+    override val carrierId: State<Int> = activeRepo.flatMap { it.carrierId }
 
-    override val cdmaRoaming =
-        activeRepo
-            .flatMapLatest { it.cdmaRoaming }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.cdmaRoaming.value)
+    override val cdmaRoaming: State<Boolean> = activeRepo.flatMap { it.cdmaRoaming }
 
-    override val isEmergencyOnly =
+    override val isEmergencyOnly: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.isEmergencyOnly }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_EMERGENCY,
-                initialValue = activeRepo.value.isEmergencyOnly.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.isEmergencyOnly.value,
-            )
+            .flatMap { it.isEmergencyOnly }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_EMERGENCY) }
+            }
 
-    override val isRoaming =
+    override val isRoaming: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.isRoaming }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_ROAMING,
-                initialValue = activeRepo.value.isRoaming.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.isRoaming.value)
+            .flatMap { it.isRoaming }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_ROAMING) } }
 
-    override val operatorAlphaShort =
+    override val operatorAlphaShort: State<String?> =
         activeRepo
-            .flatMapLatest { it.operatorAlphaShort }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_OPERATOR,
-                initialValue = activeRepo.value.operatorAlphaShort.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.operatorAlphaShort.value,
-            )
+            .flatMap { it.operatorAlphaShort }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_OPERATOR) }
+            }
 
-    override val isInService =
+    override val isInService: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.isInService }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_IS_IN_SERVICE,
-                initialValue = activeRepo.value.isInService.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.isInService.value)
+            .flatMap { it.isInService }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_IS_IN_SERVICE) }
+            }
 
-    override val isNonTerrestrial =
+    override val isNonTerrestrial: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.isNonTerrestrial }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_IS_NTN,
-                initialValue = activeRepo.value.isNonTerrestrial.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.isNonTerrestrial.value,
-            )
+            .flatMap { it.isNonTerrestrial }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_IS_NTN) } }
 
-    override val isGsm =
+    override val isGsm: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.isGsm }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_IS_GSM,
-                initialValue = activeRepo.value.isGsm.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.isGsm.value)
+            .flatMap { it.isGsm }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_IS_GSM) } }
 
-    override val cdmaLevel =
+    override val cdmaLevel: State<Int> =
         activeRepo
-            .flatMapLatest { it.cdmaLevel }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_CDMA_LEVEL,
-                initialValue = activeRepo.value.cdmaLevel.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.cdmaLevel.value)
+            .flatMap { it.cdmaLevel }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_CDMA_LEVEL) }
+            }
 
-    override val primaryLevel =
+    override val primaryLevel: State<Int> =
         activeRepo
-            .flatMapLatest { it.primaryLevel }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_PRIMARY_LEVEL,
-                initialValue = activeRepo.value.primaryLevel.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.primaryLevel.value)
+            .flatMap { it.primaryLevel }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = COL_PRIMARY_LEVEL) }
+            }
 
-    override val satelliteLevel: StateFlow<Int> =
+    override val satelliteLevel: State<Int> =
         activeRepo
-            .flatMapLatest { it.satelliteLevel }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_SATELLITE_LEVEL,
-                initialValue = activeRepo.value.satelliteLevel.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.satelliteLevel.value)
+            .flatMap { it.satelliteLevel }
+            .also {
+                onActivated {
+                    logDiffsForTable(it, tableLogBuffer, columnName = COL_SATELLITE_LEVEL)
+                }
+            }
 
-    override val dataConnectionState =
+    override val dataConnectionState: State<DataConnectionState> =
         activeRepo
-            .flatMapLatest { it.dataConnectionState }
-            .logDiffsForTable(
-                tableLogBuffer,
-                initialValue = activeRepo.value.dataConnectionState.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.dataConnectionState.value,
-            )
+            .flatMap { it.dataConnectionState }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnPrefix = "") } }
 
-    override val dataActivityDirection =
+    override val dataActivityDirection: State<DataActivityModel> =
         activeRepo
-            .flatMapLatest { it.dataActivityDirection }
-            .logDiffsForTable(
-                tableLogBuffer,
-                initialValue = activeRepo.value.dataActivityDirection.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.dataActivityDirection.value,
-            )
+            .flatMap { it.dataActivityDirection }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnPrefix = "") } }
 
-    override val carrierNetworkChangeActive =
+    override val carrierNetworkChangeActive: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.carrierNetworkChangeActive }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = COL_CARRIER_NETWORK_CHANGE,
-                initialValue = activeRepo.value.carrierNetworkChangeActive.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.carrierNetworkChangeActive.value,
-            )
+            .flatMap { it.carrierNetworkChangeActive }
+            .also {
+                onActivated {
+                    logDiffsForTable(it, tableLogBuffer, columnName = COL_CARRIER_NETWORK_CHANGE)
+                }
+            }
 
-    override val resolvedNetworkType =
+    override val resolvedNetworkType: State<ResolvedNetworkType> =
         activeRepo
-            .flatMapLatest { it.resolvedNetworkType }
-            .logDiffsForTable(
-                tableLogBuffer,
-                initialValue = activeRepo.value.resolvedNetworkType.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.resolvedNetworkType.value,
-            )
+            .flatMap { it.resolvedNetworkType }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnPrefix = "") } }
 
-    override val dataEnabled =
+    override val dataEnabled: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.dataEnabled }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = "dataEnabled",
-                initialValue = activeRepo.value.dataEnabled.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.dataEnabled.value)
+            .flatMap { it.dataEnabled }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = "dataEnabled") }
+            }
 
-    override val inflateSignalStrength =
+    override val inflateSignalStrength: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.inflateSignalStrength }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = "inflate",
-                initialValue = activeRepo.value.inflateSignalStrength.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.inflateSignalStrength.value,
-            )
+            .flatMap { it.inflateSignalStrength }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnName = "inflate") } }
 
-    override val allowNetworkSliceIndicator =
+    override val allowNetworkSliceIndicator: State<Boolean> =
         activeRepo
-            .flatMapLatest { it.allowNetworkSliceIndicator }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnName = "allowSlice",
-                initialValue = activeRepo.value.allowNetworkSliceIndicator.value,
-            )
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.allowNetworkSliceIndicator.value,
-            )
+            .flatMap { it.allowNetworkSliceIndicator }
+            .also {
+                onActivated { logDiffsForTable(it, tableLogBuffer, columnName = "allowSlice") }
+            }
 
-    override val numberOfLevels =
+    override val numberOfLevels: State<Int> = activeRepo.flatMap { it.numberOfLevels }
+
+    override val networkName: State<NetworkNameModel> =
         activeRepo
-            .flatMapLatest { it.numberOfLevels }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.numberOfLevels.value)
+            .flatMap { it.networkName }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnPrefix = "intent") } }
 
-    override val networkName =
+    override val carrierName: State<NetworkNameModel> =
         activeRepo
-            .flatMapLatest { it.networkName }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnPrefix = "intent",
-                initialValue = activeRepo.value.networkName.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.networkName.value)
+            .flatMap { it.carrierName }
+            .also { onActivated { logDiffsForTable(it, tableLogBuffer, columnPrefix = "sub") } }
 
-    override val carrierName =
-        activeRepo
-            .flatMapLatest { it.carrierName }
-            .logDiffsForTable(
-                tableLogBuffer,
-                columnPrefix = "sub",
-                initialValue = activeRepo.value.carrierName.value,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.carrierName.value)
+    override val isAllowedDuringAirplaneMode: State<Boolean> =
+        activeRepo.flatMap { it.isAllowedDuringAirplaneMode }
 
-    override val isAllowedDuringAirplaneMode =
-        activeRepo
-            .flatMapLatest { it.isAllowedDuringAirplaneMode }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.isAllowedDuringAirplaneMode.value,
-            )
+    override val hasPrioritizedNetworkCapabilities: State<Boolean> =
+        activeRepo.flatMap { it.hasPrioritizedNetworkCapabilities }
 
-    override val hasPrioritizedNetworkCapabilities =
-        activeRepo
-            .flatMapLatest { it.hasPrioritizedNetworkCapabilities }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                activeRepo.value.hasPrioritizedNetworkCapabilities.value,
-            )
+    override val isInEcmMode: State<Boolean> = activeRepo.flatMap { it.isInEcmMode }
 
-    override suspend fun isInEcmMode(): Boolean = activeRepo.value.isInEcmMode()
+    private var dumpCache: DumpCache? = null
+
+    private data class DumpCache(
+        val isCarrierMerged: Boolean,
+        val activeRepo: MobileConnectionRepositoryKairos,
+    )
 
     fun dump(pw: PrintWriter) {
+        val cache = dumpCache ?: return
         val ipw = IndentingPrintWriter(pw, "  ")
 
         ipw.println("MobileConnectionRepository[$subId]")
         ipw.increaseIndent()
 
-        ipw.println("carrierMerged=${_isCarrierMerged.value}")
+        ipw.println("carrierMerged=${cache.isCarrierMerged}")
 
         ipw.print("Type (cellular or carrier merged): ")
-        when (activeRepo.value) {
-            is CarrierMergedConnectionRepository -> ipw.println("Carrier merged")
-            is MobileConnectionRepositoryImpl -> ipw.println("Cellular")
+        when (cache.activeRepo) {
+            is CarrierMergedConnectionRepositoryKairos -> ipw.println("Carrier merged")
+            is MobileConnectionRepositoryKairosImpl -> ipw.println("Cellular")
         }
 
         ipw.increaseIndent()
-        ipw.println("Provider: ${activeRepo.value}")
+        ipw.println("Provider: ${cache.activeRepo}")
         ipw.decreaseIndent()
 
         ipw.decreaseIndent()
     }
 
-    class Factory
-    @Inject
-    constructor(
-        @Background private val scope: CoroutineScope,
-        private val logFactory: TableLogBufferFactory,
-        private val mobileRepoFactory: MobileConnectionRepositoryImpl.Factory,
-        private val carrierMergedRepoFactory: CarrierMergedConnectionRepository.Factory,
-    ) {
-        fun build(
+    @AssistedFactory
+    interface Factory {
+        fun create(
             subId: Int,
-            startingIsCarrierMerged: Boolean,
-            subscriptionModel: Flow<SubscriptionModel?>,
-            defaultNetworkName: NetworkNameModel,
-            networkNameSeparator: String,
-        ): FullMobileConnectionRepositoryKairos {
-            val mobileLogger =
-                logFactory.getOrCreate(tableBufferLogName(subId), MOBILE_CONNECTION_BUFFER_SIZE)
-
-            return FullMobileConnectionRepositoryKairos(
-                subId,
-                startingIsCarrierMerged,
-                mobileLogger,
-                subscriptionModel,
-                defaultNetworkName,
-                networkNameSeparator,
-                scope,
-                mobileRepoFactory,
-                carrierMergedRepoFactory,
-            )
-        }
-
-        companion object {
-            /** The buffer size to use for logging. */
-            const val MOBILE_CONNECTION_BUFFER_SIZE = 100
-
-            /** Returns a log buffer name for a mobile connection with the given [subId]. */
-            fun tableBufferLogName(subId: Int): String = "MobileConnectionLog[$subId]"
-        }
+            mobileLogger: TableLogBuffer,
+            isCarrierMerged: State<Boolean>,
+            mobileRepo: MobileConnectionRepositoryKairos,
+            mergedRepoSpec: BuildSpec<MobileConnectionRepositoryKairos>,
+        ): FullMobileConnectionRepositoryKairos
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index b4a45e2..bf7c299 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -542,6 +542,10 @@
 
     data class OnCarrierRoamingNtnSignalStrengthChanged(val signalStrength: NtnSignalStrength) :
         CallbackEvent
+
+    data class OnCallBackModeStarted(val type: Int) : CallbackEvent
+
+    data class OnCallBackModeStopped(val type: Int) : CallbackEvent
 }
 
 /**
@@ -560,6 +564,8 @@
     val onCarrierRoamingNtnSignalStrengthChanged:
         CallbackEvent.OnCarrierRoamingNtnSignalStrengthChanged? =
         null,
+    val addedCallbackModes: Set<Int> = emptySet(),
+    val removedCallbackModes: Set<Int> = emptySet(),
 ) {
     fun applyEvent(event: CallbackEvent): TelephonyCallbackState {
         return when (event) {
@@ -578,6 +584,37 @@
             is CallbackEvent.OnSignalStrengthChanged -> copy(onSignalStrengthChanged = event)
             is CallbackEvent.OnCarrierRoamingNtnSignalStrengthChanged ->
                 copy(onCarrierRoamingNtnSignalStrengthChanged = event)
+            is CallbackEvent.OnCallBackModeStarted -> {
+                copy(
+                    addedCallbackModes =
+                        if (event.type !in removedCallbackModes) {
+                            addedCallbackModes + event.type
+                        } else {
+                            addedCallbackModes
+                        },
+                    removedCallbackModes =
+                        if (event.type !in addedCallbackModes) {
+                            removedCallbackModes - event.type
+                        } else {
+                            removedCallbackModes
+                        },
+                )
+            }
+            is CallbackEvent.OnCallBackModeStopped ->
+                copy(
+                    addedCallbackModes =
+                        if (event.type !in removedCallbackModes) {
+                            addedCallbackModes - event.type
+                        } else {
+                            addedCallbackModes
+                        },
+                    removedCallbackModes =
+                        if (event.type !in addedCallbackModes) {
+                            removedCallbackModes + event.type
+                        } else {
+                            removedCallbackModes
+                        },
+                )
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosAdapter.kt
new file mode 100644
index 0000000..9b37f48
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosAdapter.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
+
+import com.android.systemui.kairos.BuildScope
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import com.android.systemui.util.kotlin.Producer
+import kotlinx.coroutines.flow.StateFlow
+
+@ExperimentalKairosApi
+fun BuildScope.MobileConnectionRepositoryKairosAdapter(
+    kairosRepo: MobileConnectionRepositoryKairos,
+    carrierConfig: SystemUiCarrierConfig,
+) =
+    MobileConnectionRepositoryKairosAdapter(
+        subId = kairosRepo.subId,
+        carrierId = kairosRepo.carrierId.toStateFlow(),
+        inflateSignalStrength = carrierConfig.shouldInflateSignalStrength,
+        allowNetworkSliceIndicator = carrierConfig.allowNetworkSliceIndicator,
+        tableLogBuffer = kairosRepo.tableLogBuffer,
+        isEmergencyOnly = kairosRepo.isEmergencyOnly.toStateFlow(),
+        isRoaming = kairosRepo.isRoaming.toStateFlow(),
+        operatorAlphaShort = kairosRepo.operatorAlphaShort.toStateFlow(),
+        isInService = kairosRepo.isInService.toStateFlow(),
+        isNonTerrestrial = kairosRepo.isNonTerrestrial.toStateFlow(),
+        isGsm = kairosRepo.isGsm.toStateFlow(),
+        cdmaLevel = kairosRepo.cdmaLevel.toStateFlow(),
+        primaryLevel = kairosRepo.primaryLevel.toStateFlow(),
+        satelliteLevel = kairosRepo.satelliteLevel.toStateFlow(),
+        dataConnectionState = kairosRepo.dataConnectionState.toStateFlow(),
+        dataActivityDirection = kairosRepo.dataActivityDirection.toStateFlow(),
+        carrierNetworkChangeActive = kairosRepo.carrierNetworkChangeActive.toStateFlow(),
+        resolvedNetworkType = kairosRepo.resolvedNetworkType.toStateFlow(),
+        numberOfLevels = kairosRepo.numberOfLevels.toStateFlow(),
+        dataEnabled = kairosRepo.dataEnabled.toStateFlow(),
+        cdmaRoaming = kairosRepo.cdmaRoaming.toStateFlow(),
+        networkName = kairosRepo.networkName.toStateFlow(),
+        carrierName = kairosRepo.carrierName.toStateFlow(),
+        isAllowedDuringAirplaneMode = kairosRepo.isAllowedDuringAirplaneMode.toStateFlow(),
+        hasPrioritizedNetworkCapabilities =
+            kairosRepo.hasPrioritizedNetworkCapabilities.toStateFlow(),
+        isInEcmMode = { kairosNetwork.transact { kairosRepo.isInEcmMode.sample() } },
+    )
+
+@ExperimentalKairosApi
+class MobileConnectionRepositoryKairosAdapter(
+    override val subId: Int,
+    override val carrierId: StateFlow<Int>,
+    override val inflateSignalStrength: StateFlow<Boolean>,
+    override val allowNetworkSliceIndicator: StateFlow<Boolean>,
+    override val tableLogBuffer: TableLogBuffer,
+    override val isEmergencyOnly: StateFlow<Boolean>,
+    override val isRoaming: StateFlow<Boolean>,
+    override val operatorAlphaShort: StateFlow<String?>,
+    override val isInService: StateFlow<Boolean>,
+    override val isNonTerrestrial: StateFlow<Boolean>,
+    override val isGsm: StateFlow<Boolean>,
+    override val cdmaLevel: StateFlow<Int>,
+    override val primaryLevel: StateFlow<Int>,
+    override val satelliteLevel: StateFlow<Int>,
+    override val dataConnectionState: StateFlow<DataConnectionState>,
+    override val dataActivityDirection: StateFlow<DataActivityModel>,
+    override val carrierNetworkChangeActive: StateFlow<Boolean>,
+    override val resolvedNetworkType: StateFlow<ResolvedNetworkType>,
+    override val numberOfLevels: StateFlow<Int>,
+    override val dataEnabled: StateFlow<Boolean>,
+    override val cdmaRoaming: StateFlow<Boolean>,
+    override val networkName: StateFlow<NetworkNameModel>,
+    override val carrierName: StateFlow<NetworkNameModel>,
+    override val isAllowedDuringAirplaneMode: StateFlow<Boolean>,
+    override val hasPrioritizedNetworkCapabilities: StateFlow<Boolean>,
+    private val isInEcmMode: Producer<Boolean>,
+) : MobileConnectionRepository {
+    override suspend fun isInEcmMode(): Boolean = isInEcmMode.get()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosImpl.kt
index a074acd..abe72e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryKairosImpl.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,16 +41,30 @@
 import android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID
 import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
 import android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID
-import android.telephony.satellite.NtnSignalStrength
 import com.android.settingslib.Utils
+import com.android.systemui.KairosBuilder
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO
+import com.android.systemui.kairos.Events
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.Transactional
+import com.android.systemui.kairos.awaitClose
+import com.android.systemui.kairos.coalescingEvents
+import com.android.systemui.kairos.conflatedEvents
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapNotNull
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairos.transactionally
+import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Disconnected
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
@@ -58,57 +72,47 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
-import javax.inject.Inject
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.time.Duration
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.asExecutor
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.callbackFlow
 import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.mapNotNull
-import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.scan
-import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
 
 /**
  * A repository implementation for a typical mobile connection (as opposed to a carrier merged
  * connection -- see [CarrierMergedConnectionRepository]).
  */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-class MobileConnectionRepositoryKairosImpl(
-    override val subId: Int,
+@ExperimentalKairosApi
+class MobileConnectionRepositoryKairosImpl
+@AssistedInject
+constructor(
+    @Assisted override val subId: Int,
     private val context: Context,
-    subscriptionModel: Flow<SubscriptionModel?>,
-    defaultNetworkName: NetworkNameModel,
-    networkNameSeparator: String,
+    @Assisted subscriptionModel: State<SubscriptionModel?>,
+    @Assisted defaultNetworkName: NetworkNameModel,
+    @Assisted networkNameSeparator: String,
     connectivityManager: ConnectivityManager,
-    private val telephonyManager: TelephonyManager,
-    systemUiCarrierConfig: SystemUiCarrierConfig,
+    @Assisted private val telephonyManager: TelephonyManager,
+    @Assisted systemUiCarrierConfig: SystemUiCarrierConfig,
     broadcastDispatcher: BroadcastDispatcher,
     private val mobileMappingsProxy: MobileMappingsProxy,
-    private val bgDispatcher: CoroutineDispatcher,
+    @Background private val bgDispatcher: CoroutineDispatcher,
     logger: MobileInputLogger,
-    override val tableLogBuffer: TableLogBuffer,
+    @Assisted override val tableLogBuffer: TableLogBuffer,
     flags: FeatureFlagsClassic,
-    scope: CoroutineScope,
-) : MobileConnectionRepository, MobileConnectionRepositoryKairos {
+) : MobileConnectionRepositoryKairos, KairosBuilder by kairosBuilder() {
+
     init {
         if (telephonyManager.subscriptionId != subId) {
             throw IllegalStateException(
@@ -135,240 +139,225 @@
      * it tracked. We use the [scan] operator here to track the most recent callback of _each type_
      * here. See [TelephonyCallbackState] to see how the callbacks are stored.
      */
-    private val callbackEvents: StateFlow<TelephonyCallbackState> = run {
-        val initial = TelephonyCallbackState()
-        callbackFlow {
-                val callback =
-                    object :
-                        TelephonyCallback(),
-                        TelephonyCallback.CarrierNetworkListener,
-                        TelephonyCallback.CarrierRoamingNtnListener,
-                        TelephonyCallback.DataActivityListener,
-                        TelephonyCallback.DataConnectionStateListener,
-                        TelephonyCallback.DataEnabledListener,
-                        TelephonyCallback.DisplayInfoListener,
-                        TelephonyCallback.ServiceStateListener,
-                        TelephonyCallback.SignalStrengthsListener {
+    private val callbackEvents: Events<TelephonyCallbackState> = buildEvents {
+        coalescingEvents(
+            initialValue = TelephonyCallbackState(),
+            coalesce = TelephonyCallbackState::applyEvent,
+        ) {
+            val callback =
+                object :
+                    TelephonyCallback(),
+                    TelephonyCallback.CarrierNetworkListener,
+                    TelephonyCallback.CarrierRoamingNtnListener,
+                    TelephonyCallback.DataActivityListener,
+                    TelephonyCallback.DataConnectionStateListener,
+                    TelephonyCallback.DataEnabledListener,
+                    TelephonyCallback.DisplayInfoListener,
+                    TelephonyCallback.ServiceStateListener,
+                    TelephonyCallback.SignalStrengthsListener,
+                    TelephonyCallback.EmergencyCallbackModeListener {
 
-                        override fun onCarrierNetworkChange(active: Boolean) {
-                            logger.logOnCarrierNetworkChange(active, subId)
-                            trySend(CallbackEvent.OnCarrierNetworkChange(active))
-                        }
-
-                        override fun onCarrierRoamingNtnModeChanged(active: Boolean) {
-                            logger.logOnCarrierRoamingNtnModeChanged(active)
-                            trySend(CallbackEvent.OnCarrierRoamingNtnModeChanged(active))
-                        }
-
-                        override fun onDataActivity(direction: Int) {
-                            logger.logOnDataActivity(direction, subId)
-                            trySend(CallbackEvent.OnDataActivity(direction))
-                        }
-
-                        override fun onDataEnabledChanged(enabled: Boolean, reason: Int) {
-                            logger.logOnDataEnabledChanged(enabled, subId)
-                            trySend(CallbackEvent.OnDataEnabledChanged(enabled))
-                        }
-
-                        override fun onDataConnectionStateChanged(
-                            dataState: Int,
-                            networkType: Int,
-                        ) {
-                            logger.logOnDataConnectionStateChanged(dataState, networkType, subId)
-                            trySend(CallbackEvent.OnDataConnectionStateChanged(dataState))
-                        }
-
-                        override fun onDisplayInfoChanged(
-                            telephonyDisplayInfo: TelephonyDisplayInfo
-                        ) {
-                            logger.logOnDisplayInfoChanged(telephonyDisplayInfo, subId)
-                            trySend(CallbackEvent.OnDisplayInfoChanged(telephonyDisplayInfo))
-                        }
-
-                        override fun onServiceStateChanged(serviceState: ServiceState) {
-                            logger.logOnServiceStateChanged(serviceState, subId)
-                            trySend(CallbackEvent.OnServiceStateChanged(serviceState))
-                        }
-
-                        override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
-                            logger.logOnSignalStrengthsChanged(signalStrength, subId)
-                            trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength))
-                        }
-
-                        override fun onCarrierRoamingNtnSignalStrengthChanged(
-                            signalStrength: NtnSignalStrength
-                        ) {
-                            logger.logNtnSignalStrengthChanged(signalStrength)
-                            trySend(
-                                CallbackEvent.OnCarrierRoamingNtnSignalStrengthChanged(
-                                    signalStrength
-                                )
-                            )
-                        }
+                    override fun onCarrierNetworkChange(active: Boolean) {
+                        logger.logOnCarrierNetworkChange(active, subId)
+                        emit(CallbackEvent.OnCarrierNetworkChange(active))
                     }
+
+                    override fun onCarrierRoamingNtnModeChanged(active: Boolean) {
+                        logger.logOnCarrierRoamingNtnModeChanged(active)
+                        emit(CallbackEvent.OnCarrierRoamingNtnModeChanged(active))
+                    }
+
+                    override fun onDataActivity(direction: Int) {
+                        logger.logOnDataActivity(direction, subId)
+                        emit(CallbackEvent.OnDataActivity(direction))
+                    }
+
+                    override fun onDataEnabledChanged(enabled: Boolean, reason: Int) {
+                        logger.logOnDataEnabledChanged(enabled, subId)
+                        emit(CallbackEvent.OnDataEnabledChanged(enabled))
+                    }
+
+                    override fun onDataConnectionStateChanged(dataState: Int, networkType: Int) {
+                        logger.logOnDataConnectionStateChanged(dataState, networkType, subId)
+                        emit(CallbackEvent.OnDataConnectionStateChanged(dataState))
+                    }
+
+                    override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
+                        logger.logOnDisplayInfoChanged(telephonyDisplayInfo, subId)
+                        emit(CallbackEvent.OnDisplayInfoChanged(telephonyDisplayInfo))
+                    }
+
+                    override fun onServiceStateChanged(serviceState: ServiceState) {
+                        logger.logOnServiceStateChanged(serviceState, subId)
+                        emit(CallbackEvent.OnServiceStateChanged(serviceState))
+                    }
+
+                    override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
+                        logger.logOnSignalStrengthsChanged(signalStrength, subId)
+                        emit(CallbackEvent.OnSignalStrengthChanged(signalStrength))
+                    }
+
+                    override fun onCallbackModeStarted(
+                        type: Int,
+                        timerDuration: Duration,
+                        subId: Int,
+                    ) {
+                        // logger.logOnCallBackModeStarted(type, subId)
+                        emit(CallbackEvent.OnCallBackModeStarted(type))
+                    }
+
+                    override fun onCallbackModeRestarted(
+                        type: Int,
+                        timerDuration: Duration,
+                        subId: Int,
+                    ) {
+                        // no-op
+                    }
+
+                    override fun onCallbackModeStopped(type: Int, reason: Int, subId: Int) {
+                        // logger.logOnCallBackModeStopped(type, reason, subId)
+                        emit(CallbackEvent.OnCallBackModeStopped(type))
+                    }
+                }
+            withContext(bgDispatcher) {
                 telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback)
-                awaitClose { telephonyManager.unregisterTelephonyCallback(callback) }
             }
-            .flowOn(bgDispatcher)
-            .scan(initial = initial) { state, event -> state.applyEvent(event) }
-            .stateIn(scope = scope, started = SharingStarted.WhileSubscribed(), initial)
+            awaitClose { telephonyManager.unregisterTelephonyCallback(callback) }
+        }
     }
 
-    override val isEmergencyOnly =
-        callbackEvents
-            .mapNotNull { it.onServiceStateChanged }
-            .map { it.serviceState.isEmergencyOnly }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+    private val serviceState: State<ServiceState?> = buildState {
+        callbackEvents.mapNotNull { it.onServiceStateChanged?.serviceState }.holdState(null)
+    }
 
-    override val isRoaming =
+    override val isEmergencyOnly: State<Boolean> = serviceState.map { it?.isEmergencyOnly == true }
+
+    private val displayInfo: State<TelephonyDisplayInfo?> = buildState {
+        callbackEvents.mapNotNull { it.onDisplayInfoChanged?.telephonyDisplayInfo }.holdState(null)
+    }
+
+    override val isRoaming: State<Boolean> =
         if (flags.isEnabled(ROAMING_INDICATOR_VIA_DISPLAY_INFO)) {
-                callbackEvents
-                    .mapNotNull { it.onDisplayInfoChanged }
-                    .map { it.telephonyDisplayInfo.isRoaming }
+            displayInfo.map { it?.isRoaming == true }
+        } else {
+            serviceState.map { it?.roaming == true }
+        }
+
+    override val operatorAlphaShort: State<String?> = serviceState.map { it?.operatorAlphaShort }
+
+    override val isInService: State<Boolean> =
+        serviceState.map { it?.let(Utils::isInService) == true }
+
+    private val carrierRoamingNtnActive: State<Boolean> = buildState {
+        callbackEvents.mapNotNull { it.onCarrierRoamingNtnModeChanged?.active }.holdState(false)
+    }
+
+    override val isNonTerrestrial: State<Boolean>
+        get() = carrierRoamingNtnActive
+
+    private val signalStrength: State<SignalStrength?> = buildState {
+        callbackEvents.mapNotNull { it.onSignalStrengthChanged?.signalStrength }.holdState(null)
+    }
+
+    override val isGsm: State<Boolean> = signalStrength.map { it?.isGsm == true }
+
+    override val cdmaLevel: State<Int> =
+        signalStrength.map {
+            it?.getCellSignalStrengths(CellSignalStrengthCdma::class.java)?.firstOrNull()?.level
+                ?: SIGNAL_STRENGTH_NONE_OR_UNKNOWN
+        }
+
+    override val primaryLevel: State<Int> =
+        signalStrength.map { it?.level ?: SIGNAL_STRENGTH_NONE_OR_UNKNOWN }
+
+    override val satelliteLevel: State<Int> = buildState {
+        callbackEvents
+            .mapNotNull { it.onCarrierRoamingNtnSignalStrengthChanged?.signalStrength?.level }
+            .holdState(0)
+    }
+
+    override val dataConnectionState: State<DataConnectionState> = buildState {
+        callbackEvents
+            .mapNotNull { it.onDataConnectionStateChanged?.dataState?.toDataConnectionType() }
+            .holdState(Disconnected)
+    }
+
+    override val dataActivityDirection: State<DataActivityModel> = buildState {
+        callbackEvents
+            .mapNotNull { it.onDataActivity?.direction?.toMobileDataActivityModel() }
+            .holdState(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
+    }
+
+    override val carrierNetworkChangeActive: State<Boolean> = buildState {
+        callbackEvents.mapNotNull { it.onCarrierNetworkChange?.active }.holdState(false)
+    }
+
+    private val telephonyDisplayInfo: State<TelephonyDisplayInfo?> = buildState {
+        callbackEvents.mapNotNull { it.onDisplayInfoChanged?.telephonyDisplayInfo }.holdState(null)
+    }
+
+    override val resolvedNetworkType: State<ResolvedNetworkType> =
+        telephonyDisplayInfo.map { displayInfo ->
+            displayInfo
+                ?.overrideNetworkType
+                ?.takeIf { it != OVERRIDE_NETWORK_TYPE_NONE }
+                ?.let { OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(it)) }
+                ?: displayInfo
+                    ?.networkType
+                    ?.takeIf { it != NETWORK_TYPE_UNKNOWN }
+                    ?.let { DefaultNetworkType(mobileMappingsProxy.toIconKey(it)) }
+                ?: UnknownNetworkType
+        }
+
+    override val inflateSignalStrength: State<Boolean> = buildState {
+        systemUiCarrierConfig.shouldInflateSignalStrength.toState()
+    }
+
+    override val allowNetworkSliceIndicator: State<Boolean> = buildState {
+        systemUiCarrierConfig.allowNetworkSliceIndicator.toState()
+    }
+
+    override val numberOfLevels: State<Int> =
+        inflateSignalStrength.map { shouldInflate ->
+            if (shouldInflate) {
+                DEFAULT_NUM_LEVELS + 1
             } else {
-                callbackEvents
-                    .mapNotNull { it.onServiceStateChanged }
-                    .map { it.serviceState.roaming }
+                DEFAULT_NUM_LEVELS
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+        }
 
-    override val operatorAlphaShort =
-        callbackEvents
-            .mapNotNull { it.onServiceStateChanged }
-            .map { it.serviceState.operatorAlphaShort }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-
-    override val isInService =
-        callbackEvents
-            .mapNotNull { it.onServiceStateChanged }
-            .map { Utils.isInService(it.serviceState) }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    override val isNonTerrestrial =
-        callbackEvents
-            .mapNotNull { it.onCarrierRoamingNtnModeChanged }
-            .map { it.active }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    override val isGsm =
-        callbackEvents
-            .mapNotNull { it.onSignalStrengthChanged }
-            .map { it.signalStrength.isGsm }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    override val cdmaLevel =
-        callbackEvents
-            .mapNotNull { it.onSignalStrengthChanged }
-            .map {
-                it.signalStrength.getCellSignalStrengths(CellSignalStrengthCdma::class.java).let {
-                    strengths ->
-                    if (strengths.isNotEmpty()) {
-                        strengths[0].level
-                    } else {
-                        SIGNAL_STRENGTH_NONE_OR_UNKNOWN
-                    }
-                }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
-
-    override val primaryLevel =
-        callbackEvents
-            .mapNotNull { it.onSignalStrengthChanged }
-            .map { it.signalStrength.level }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
-
-    override val satelliteLevel: StateFlow<Int> =
-        callbackEvents
-            .mapNotNull { it.onCarrierRoamingNtnSignalStrengthChanged }
-            .map { it.signalStrength.level }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), 0)
-
-    override val dataConnectionState =
-        callbackEvents
-            .mapNotNull { it.onDataConnectionStateChanged }
-            .map { it.dataState.toDataConnectionType() }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), Disconnected)
-
-    override val dataActivityDirection =
-        callbackEvents
-            .mapNotNull { it.onDataActivity }
-            .map { it.direction.toMobileDataActivityModel() }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                DataActivityModel(hasActivityIn = false, hasActivityOut = false),
-            )
-
-    override val carrierNetworkChangeActive =
-        callbackEvents
-            .mapNotNull { it.onCarrierNetworkChange }
-            .map { it.active }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    override val resolvedNetworkType =
-        callbackEvents
-            .mapNotNull { it.onDisplayInfoChanged }
-            .map {
-                if (it.telephonyDisplayInfo.overrideNetworkType != OVERRIDE_NETWORK_TYPE_NONE) {
-                    OverrideNetworkType(
-                        mobileMappingsProxy.toIconKeyOverride(
-                            it.telephonyDisplayInfo.overrideNetworkType
-                        )
-                    )
-                } else if (it.telephonyDisplayInfo.networkType != NETWORK_TYPE_UNKNOWN) {
-                    DefaultNetworkType(
-                        mobileMappingsProxy.toIconKey(it.telephonyDisplayInfo.networkType)
-                    )
-                } else {
-                    UnknownNetworkType
-                }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), UnknownNetworkType)
-
-    override val inflateSignalStrength = systemUiCarrierConfig.shouldInflateSignalStrength
-    override val allowNetworkSliceIndicator = systemUiCarrierConfig.allowNetworkSliceIndicator
-
-    override val numberOfLevels =
-        inflateSignalStrength
-            .map { shouldInflate ->
-                if (shouldInflate) {
-                    DEFAULT_NUM_LEVELS + 1
-                } else {
-                    DEFAULT_NUM_LEVELS
-                }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
-
-    override val carrierName =
-        subscriptionModel
-            .map {
-                it?.let { model -> NetworkNameModel.SubscriptionDerived(model.carrierName) }
-                    ?: defaultNetworkName
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName)
+    override val carrierName: State<NetworkNameModel> =
+        subscriptionModel.map {
+            it?.let { model -> NetworkNameModel.SubscriptionDerived(model.carrierName) }
+                ?: defaultNetworkName
+        }
 
     /**
      * There are a few cases where we will need to poll [TelephonyManager] so we can update some
      * internal state where callbacks aren't provided. Any of those events should be merged into
      * this flow, which can be used to trigger the polling.
      */
-    private val telephonyPollingEvent: Flow<Unit> = callbackEvents.map { Unit }
+    private val telephonyPollingEvent: Events<Unit> = callbackEvents.map {}
 
-    override val cdmaRoaming: StateFlow<Boolean> =
+    private val cdmaEnhancedRoamingIndicatorDisplayNumber: Transactional<Int?> = transactionally {
+        try {
+            telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber
+        } catch (e: UnsupportedOperationException) {
+            // Handles the same as a function call failure
+            null
+        }
+    }
+
+    override val cdmaRoaming: State<Boolean> = buildState {
         telephonyPollingEvent
-            .mapLatest {
-                try {
-                    val cdmaEri = telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber
-                    cdmaEri == ERI_ON || cdmaEri == ERI_FLASH
-                } catch (e: UnsupportedOperationException) {
-                    // Handles the same as a function call failure
-                    false
-                }
+            .map {
+                val cdmaEri = cdmaEnhancedRoamingIndicatorDisplayNumber.sample()
+                cdmaEri == ERI_ON || cdmaEri == ERI_FLASH
             }
-            .flowOn(bgDispatcher)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+            .holdState(false)
+    }
 
-    override val carrierId =
+    override val carrierId: State<Int> = buildState {
         broadcastDispatcher
             .broadcastFlow(
                 filter =
@@ -379,11 +368,8 @@
                 intent.getIntExtra(EXTRA_SUBSCRIPTION_ID, INVALID_SUBSCRIPTION_ID) == subId
             }
             .map { it.carrierId() }
-            .onStart {
-                // Make sure we get the initial carrierId
-                emit(telephonyManager.simCarrierId)
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), telephonyManager.simCarrierId)
+            .toState(telephonyManager.simCarrierId)
+    }
 
     /**
      * BroadcastDispatcher does not handle sticky broadcasts, so we can't use it here. Note that we
@@ -393,8 +379,8 @@
      * See b/322432056 for context.
      */
     @SuppressLint("RegisterReceiverViaContext")
-    override val networkName: StateFlow<NetworkNameModel> =
-        conflatedCallbackFlow {
+    override val networkName: State<NetworkNameModel> = buildState {
+        conflatedEvents {
                 val receiver =
                     object : BroadcastReceiver() {
                         override fun onReceive(context: Context, intent: Intent) {
@@ -405,7 +391,7 @@
                                 ) == subId
                             ) {
                                 logger.logServiceProvidersUpdatedBroadcast(intent)
-                                trySend(
+                                emit(
                                     intent.toNetworkNameModel(networkNameSeparator)
                                         ?: defaultNetworkName
                                 )
@@ -420,22 +406,28 @@
 
                 awaitClose { context.unregisterReceiver(receiver) }
             }
-            .flowOn(bgDispatcher)
-            .stateIn(scope, SharingStarted.Eagerly, defaultNetworkName)
-
-    override val dataEnabled = run {
-        val initial = telephonyManager.isDataConnectionAllowed
-        callbackEvents
-            .mapNotNull { it.onDataEnabledChanged }
-            .map { it.enabled }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), initial)
+            .holdState(defaultNetworkName)
     }
 
-    override suspend fun isInEcmMode(): Boolean =
-        withContext(bgDispatcher) { telephonyManager.emergencyCallbackMode }
+    override val dataEnabled: State<Boolean> = buildState {
+        callbackEvents
+            .mapNotNull { it.onDataEnabledChanged?.enabled }
+            .holdState(telephonyManager.isDataConnectionAllowed)
+    }
+
+    override val isInEcmMode: State<Boolean> = buildState {
+        callbackEvents
+            .mapNotNull {
+                (it.addedCallbackModes to it.removedCallbackModes).takeIf { (added, removed) ->
+                    added.isNotEmpty() || removed.isNotEmpty()
+                }
+            }
+            .foldState(emptySet<Int>()) { (added, removed), acc -> acc - removed + added }
+            .mapTransactionally { it.isNotEmpty() }
+    }
 
     /** Typical mobile connections aren't available during airplane mode. */
-    override val isAllowedDuringAirplaneMode = MutableStateFlow(false).asStateFlow()
+    override val isAllowedDuringAirplaneMode: State<Boolean> = stateOf(false)
 
     /**
      * Currently, a network with NET_CAPABILITY_PRIORITIZE_LATENCY is the only type of network that
@@ -444,27 +436,27 @@
      * self_certified_network_capabilities.xml config file
      */
     @SuppressLint("WrongConstant")
-    private val networkSliceRequest =
+    private val networkSliceRequest: NetworkRequest =
         NetworkRequest.Builder()
             .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
             .setSubscriptionIds(setOf(subId))
             .build()
 
     @SuppressLint("MissingPermission")
-    override val hasPrioritizedNetworkCapabilities: StateFlow<Boolean> =
-        conflatedCallbackFlow {
+    override val hasPrioritizedNetworkCapabilities: State<Boolean> = buildState {
+        conflatedEvents {
                 // Our network callback listens only for this.subId && net_cap_prioritize_latency
                 // therefore our state is a simple mapping of whether or not that network exists
                 val callback =
                     object : NetworkCallback() {
                         override fun onAvailable(network: Network) {
                             logger.logPrioritizedNetworkAvailable(network.netId)
-                            trySend(true)
+                            emit(true)
                         }
 
                         override fun onLost(network: Network) {
                             logger.logPrioritizedNetworkLost(network.netId)
-                            trySend(false)
+                            emit(false)
                         }
                     }
 
@@ -472,48 +464,20 @@
 
                 awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
             }
-            .flowOn(bgDispatcher)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+            .holdState(false)
+    }
 
-    class Factory
-    @Inject
-    constructor(
-        private val context: Context,
-        private val broadcastDispatcher: BroadcastDispatcher,
-        private val connectivityManager: ConnectivityManager,
-        private val telephonyManager: TelephonyManager,
-        private val logger: MobileInputLogger,
-        private val carrierConfigRepository: CarrierConfigRepository,
-        private val mobileMappingsProxy: MobileMappingsProxy,
-        private val flags: FeatureFlagsClassic,
-        @Background private val bgDispatcher: CoroutineDispatcher,
-        @Background private val scope: CoroutineScope,
-    ) {
-        fun build(
+    @AssistedFactory
+    fun interface Factory {
+        fun create(
             subId: Int,
             mobileLogger: TableLogBuffer,
-            subscriptionModel: Flow<SubscriptionModel?>,
+            subscriptionModel: State<SubscriptionModel?>,
             defaultNetworkName: NetworkNameModel,
             networkNameSeparator: String,
-        ): MobileConnectionRepositoryKairos {
-            return MobileConnectionRepositoryKairosImpl(
-                subId,
-                context,
-                subscriptionModel,
-                defaultNetworkName,
-                networkNameSeparator,
-                connectivityManager,
-                telephonyManager.createForSubscriptionId(subId),
-                carrierConfigRepository.getOrCreateConfigForSubId(subId),
-                broadcastDispatcher,
-                mobileMappingsProxy,
-                bgDispatcher,
-                logger,
-                mobileLogger,
-                flags,
-                scope,
-            )
-        }
+            systemUiCarrierConfig: SystemUiCarrierConfig,
+            telephonyManager: TelephonyManager,
+        ): MobileConnectionRepositoryKairosImpl
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt
index 51771dd..e468159 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,21 +27,52 @@
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import android.telephony.TelephonyCallback
 import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener
+import android.telephony.TelephonyCallback.EmergencyCallbackModeListener
 import android.telephony.TelephonyManager
 import android.util.IndentingPrintWriter
-import androidx.annotation.VisibleForTesting
 import com.android.internal.telephony.PhoneConstants
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.settingslib.SignalIcon.MobileIconGroup
 import com.android.settingslib.mobile.MobileMappings.Config
 import com.android.systemui.Dumpable
+import com.android.systemui.Flags
+import com.android.systemui.KairosActivatable
+import com.android.systemui.KairosBuilder
+import com.android.systemui.activated
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.kairos.BuildSpec
+import com.android.systemui.kairos.Events
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.Incremental
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.StateSelector
+import com.android.systemui.kairos.asIncremental
+import com.android.systemui.kairos.asyncEvent
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.changes
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.effect
+import com.android.systemui.kairos.filterNotNull
+import com.android.systemui.kairos.flatMap
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapNotNull
+import com.android.systemui.kairos.mapValues
+import com.android.systemui.kairos.mergeLeft
+import com.android.systemui.kairos.onEach
+import com.android.systemui.kairos.rebuildOn
+import com.android.systemui.kairos.selector
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairos.switchEvents
+import com.android.systemui.kairos.transitions
+import com.android.systemui.kairos.util.WithPrev
+import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository
@@ -49,39 +80,32 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepositoryKairos
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepositoryKairos
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy
+import com.android.systemui.statusbar.pipeline.shared.data.model.DefaultConnectionModel
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
-import com.android.systemui.util.kotlin.pairwise
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import dagger.Binds
+import dagger.Lazy
+import dagger.Provides
+import dagger.multibindings.ElementsIntoSet
 import java.io.PrintWriter
-import java.lang.ref.WeakReference
-import java.util.concurrent.ConcurrentHashMap
+import java.time.Duration
 import javax.inject.Inject
+import javax.inject.Provider
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.asExecutor
 import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.callbackFlow
 import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.mapNotNull
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
 
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@ExperimentalKairosApi
 @SysUISingleton
 class MobileConnectionsRepositoryKairosImpl
 @Inject
@@ -96,39 +120,26 @@
     broadcastDispatcher: BroadcastDispatcher,
     private val context: Context,
     @Background private val bgDispatcher: CoroutineDispatcher,
-    @Background private val scope: CoroutineScope,
     @Main private val mainDispatcher: CoroutineDispatcher,
     airplaneModeRepository: AirplaneModeRepository,
     // Some "wifi networks" should be rendered as a mobile connection, which is why the wifi
     // repository is an input to the mobile repository.
-    // See [CarrierMergedConnectionRepository] for details.
+    // See [CarrierMergedConnectionRepositoryKairos] for details.
     wifiRepository: WifiRepository,
-    private val fullMobileRepoFactory: FullMobileConnectionRepository.Factory,
     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
-    private val dumpManager: DumpManager,
-) : MobileConnectionsRepository, MobileConnectionsRepositoryKairos, Dumpable {
-
-    // TODO(b/333912012): for now, we are never invalidating the cache. We can do better though
-    private var subIdRepositoryCache =
-        ConcurrentHashMap<Int, WeakReference<FullMobileConnectionRepository>>()
-
-    private val defaultNetworkName =
-        NetworkNameModel.Default(
-            context.getString(com.android.internal.R.string.lockscreen_carrier_default)
-        )
-
-    private val networkNameSeparator: String =
-        context.getString(R.string.status_bar_network_name_separator)
+    dumpManager: DumpManager,
+    private val mobileRepoFactory: Lazy<ConnectionRepoFactory>,
+) : MobileConnectionsRepositoryKairos, Dumpable, KairosBuilder by kairosBuilder() {
 
     init {
-        dumpManager.registerNormalDumpable("MobileConnectionsRepository", this)
+        dumpManager.registerNormalDumpable("MobileConnectionsRepositoryKairos", this)
     }
 
-    private val carrierMergedSubId: StateFlow<Int?> =
+    private val carrierMergedSubId: State<Int?> = buildState {
         combine(
-                wifiRepository.wifiNetwork,
-                connectivityRepository.defaultConnections,
-                airplaneModeRepository.isAirplaneMode,
+                wifiRepository.wifiNetwork.toState(),
+                connectivityRepository.defaultConnections.toState(),
+                airplaneModeRepository.isAirplaneMode.toState(),
             ) { wifiNetwork, defaultConnections, isAirplaneMode ->
                 // The carrier merged connection should only be used if it's also the default
                 // connection or mobile connections aren't available because of airplane mode.
@@ -143,16 +154,12 @@
                     null
                 }
             }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                LOGGING_PREFIX,
-                columnName = "carrierMergedSubId",
-                initialValue = null,
-            )
-            .stateIn(scope, started = SharingStarted.WhileSubscribed(), null)
+            .also {
+                logDiffsForTable(it, tableLogger, LOGGING_PREFIX, columnName = "carrierMergedSubId")
+            }
+    }
 
-    private val mobileSubscriptionsChangeEvent: Flow<Unit> =
+    private val mobileSubscriptionsChangeEvent: Events<Unit> = buildEvents {
         conflatedCallbackFlow {
                 val callback =
                     object : SubscriptionManager.OnSubscriptionsChangedListener() {
@@ -161,18 +168,15 @@
                             trySend(Unit)
                         }
                     }
-
-                subscriptionManager.addOnSubscriptionsChangedListener(
-                    bgDispatcher.asExecutor(),
-                    callback,
-                )
-
+                subscriptionManager.addOnSubscriptionsChangedListener(Runnable::run, callback)
                 awaitClose { subscriptionManager.removeOnSubscriptionsChangedListener(callback) }
             }
             .flowOn(bgDispatcher)
+            .toEvents()
+    }
 
     /** Turn ACTION_SERVICE_STATE (for subId = -1) into an event */
-    private val serviceStateChangedEvent: Flow<Unit> =
+    private val serviceStateChangedEvent: Events<Unit> = buildEvents {
         broadcastDispatcher
             .broadcastFlow(IntentFilter(Intent.ACTION_SERVICE_STATE)) { intent, _ ->
                 val subId =
@@ -186,219 +190,235 @@
                     Unit
                 }
             }
-            // Emit on start so that we always check the state at least once
-            .onStart { emit(Unit) }
+            .toEvents()
+    }
 
     /** Eager flow to determine the device-based emergency calls only state */
-    override val isDeviceEmergencyCallCapable: StateFlow<Boolean> =
-        serviceStateChangedEvent
-            .mapLatest {
-                val modems = telephonyManager.activeModemCount
-
-                // Assume false for automotive devices which don't have the calling feature.
-                // TODO: b/398045526 to revisit the below.
-                val isAutomotive: Boolean =
-                    context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
-                val hasFeatureCalling: Boolean =
-                    context.packageManager.hasSystemFeature(
-                        PackageManager.FEATURE_TELEPHONY_CALLING
-                    )
-                if (isAutomotive && !hasFeatureCalling) {
-                    return@mapLatest false
-                }
-
-                // Check the service state for every modem. If any state reports emergency calling
-                // capable, then consider the device to have emergency call capabilities
-                (0..<modems)
-                    .map { telephonyManager.getServiceStateForSlot(it) }
-                    .any { it?.isEmergencyOnly == true }
+    override val isDeviceEmergencyCallCapable: State<Boolean> = buildState {
+        rebuildOn(serviceStateChangedEvent) { asyncEvent { doAnyModemsSupportEmergencyCalls() } }
+            .switchEvents()
+            .holdState(false)
+            .also {
+                logDiffsForTable(
+                    it,
+                    tableLogger,
+                    LOGGING_PREFIX,
+                    columnName = "deviceEmergencyOnly",
+                )
             }
-            .flowOn(bgDispatcher)
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                columnPrefix = LOGGING_PREFIX,
-                columnName = "deviceEmergencyOnly",
-                initialValue = false,
-            )
-            .stateIn(scope, SharingStarted.Eagerly, false)
+    }
+
+    private suspend fun doAnyModemsSupportEmergencyCalls(): Boolean =
+        withContext(bgDispatcher) {
+            val modems = telephonyManager.activeModemCount
+
+            // Assume false for automotive devices which don't have the calling feature.
+            // TODO: b/398045526 to revisit the below.
+            val isAutomotive: Boolean =
+                context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+            val hasFeatureCalling: Boolean =
+                context.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+            if (isAutomotive && !hasFeatureCalling) {
+                return@withContext false
+            }
+
+            // Check the service state for every modem. If any state reports emergency calling
+            // capable, then consider the device to have emergency call capabilities
+            (0..<modems)
+                .map { telephonyManager.getServiceStateForSlot(it) }
+                .any { it?.isEmergencyOnly == true }
+        }
 
     /**
      * State flow that emits the set of mobile data subscriptions, each represented by its own
      * [SubscriptionModel].
      */
-    override val subscriptions: StateFlow<List<SubscriptionModel>> =
-        merge(mobileSubscriptionsChangeEvent, carrierMergedSubId)
-            .mapLatest { fetchSubscriptionsList().map { it.toSubscriptionModel() } }
-            .onEach { infos -> updateRepos(infos) }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                LOGGING_PREFIX,
-                columnName = "subscriptions",
-                initialValue = listOf(),
-            )
-            .stateIn(scope, started = SharingStarted.WhileSubscribed(), listOf())
+    override val subscriptions: State<List<SubscriptionModel>> = buildState {
+        rebuildOn(mergeLeft(mobileSubscriptionsChangeEvent, carrierMergedSubId.changes)) {
+                asyncEvent { fetchSubscriptionModels() }
+            }
+            .switchEvents()
+            .holdState(emptyList())
+            .also {
+                logDiffsForTable(it, tableLogger, LOGGING_PREFIX, columnName = "subscriptions")
+            }
+    }
 
-    override val activeMobileDataSubscriptionId: StateFlow<Int?> =
-        conflatedCallbackFlow {
+    val subscriptionsById: State<Map<Int, SubscriptionModel>> =
+        subscriptions.map { subs -> subs.associateBy { it.subscriptionId } }
+
+    override val mobileConnectionsBySubId: Incremental<Int, MobileConnectionRepositoryKairos> =
+        buildIncremental {
+            subscriptionsById
+                .asIncremental()
+                .mapValues { (subId, sub) -> mobileRepoFactory.get().create(subId) }
+                .applyLatestSpecForKey()
+        }
+
+    private val telephonyManagerState: State<Pair<Int?, Set<Int>>> = buildState {
+        callbackFlow {
                 val callback =
-                    object : TelephonyCallback(), ActiveDataSubscriptionIdListener {
+                    object :
+                        TelephonyCallback(),
+                        ActiveDataSubscriptionIdListener,
+                        EmergencyCallbackModeListener {
                         override fun onActiveDataSubscriptionIdChanged(subId: Int) {
                             if (subId != INVALID_SUBSCRIPTION_ID) {
-                                trySend(subId)
+                                trySend { (_, set): Pair<Int?, Set<Int>> -> subId to set }
                             } else {
-                                trySend(null)
+                                trySend { (_, set): Pair<Int?, Set<Int>> -> null to set }
                             }
                         }
-                    }
 
-                telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback)
+                        override fun onCallbackModeStarted(
+                            type: Int,
+                            timerDuration: Duration,
+                            subId: Int,
+                        ) {
+                            trySend { (id, set): Pair<Int?, Set<Int>> -> id to (set + type) }
+                        }
+
+                        override fun onCallbackModeRestarted(
+                            type: Int,
+                            timerDuration: Duration,
+                            subId: Int,
+                        ) {
+                            // no-op
+                        }
+
+                        override fun onCallbackModeStopped(type: Int, reason: Int, subId: Int) {
+                            trySend { (id, set): Pair<Int?, Set<Int>> -> id to (set - type) }
+                        }
+                    }
+                telephonyManager.registerTelephonyCallback(Runnable::run, callback)
                 awaitClose { telephonyManager.unregisterTelephonyCallback(callback) }
             }
             .flowOn(bgDispatcher)
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                LOGGING_PREFIX,
-                columnName = "activeSubId",
-                initialValue = null,
-            )
-            .stateIn(scope, started = SharingStarted.WhileSubscribed(), null)
+            .scanToState(null to emptySet())
+    }
 
-    override val activeMobileDataRepository =
-        activeMobileDataSubscriptionId
-            .map { activeSubId ->
-                if (activeSubId == null) {
-                    null
-                } else {
-                    getOrCreateRepoForSubId(activeSubId)
+    override val activeMobileDataSubscriptionId: State<Int?> =
+        telephonyManagerState
+            .map { it.first }
+            .also {
+                onActivated {
+                    logDiffsForTable(it, tableLogger, LOGGING_PREFIX, columnName = "activeSubId")
                 }
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
 
-    override val defaultDataSubId: StateFlow<Int?> =
+    override val activeMobileDataRepository: State<MobileConnectionRepositoryKairos?> =
+        combine(activeMobileDataSubscriptionId, mobileConnectionsBySubId) { id, cache -> cache[id] }
+
+    override val defaultDataSubId: State<Int?> = buildState {
         broadcastDispatcher
             .broadcastFlow(
                 IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
             ) { intent, _ ->
-                val subId =
-                    intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID)
-                if (subId == INVALID_SUBSCRIPTION_ID) {
-                    null
-                } else {
-                    subId
-                }
+                intent
+                    .getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID)
+                    .takeIf { it != INVALID_SUBSCRIPTION_ID }
             }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                LOGGING_PREFIX,
-                columnName = "defaultSubId",
-                initialValue = null,
-            )
             .onStart {
-                val subId = subscriptionManagerProxy.getDefaultDataSubscriptionId()
-                emit(if (subId == INVALID_SUBSCRIPTION_ID) null else subId)
+                emit(
+                    subscriptionManagerProxy.getDefaultDataSubscriptionId().takeIf {
+                        it != INVALID_SUBSCRIPTION_ID
+                    }
+                )
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+            .toState(initialValue = null)
+            .also { logDiffsForTable(it, tableLogger, LOGGING_PREFIX, columnName = "defaultSubId") }
+    }
 
-    private val carrierConfigChangedEvent =
-        broadcastDispatcher
-            .broadcastFlow(IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED))
+    private val carrierConfigChangedEvent: Events<Unit> =
+        buildEvents {
+                broadcastDispatcher
+                    .broadcastFlow(IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED))
+                    .toEvents()
+            }
             .onEach { logger.logActionCarrierConfigChanged() }
 
-    override val defaultDataSubRatConfig: StateFlow<Config> =
-        merge(defaultDataSubId, carrierConfigChangedEvent)
-            .onStart { emit(Unit) }
-            .mapLatest { Config.readConfig(context) }
-            .distinctUntilChanged()
-            .onEach { logger.logDefaultDataSubRatConfig(it) }
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                initialValue = Config.readConfig(context),
-            )
+    override val defaultDataSubRatConfig: State<Config> = buildState {
+        rebuildOn(mergeLeft(defaultDataSubId.changes, carrierConfigChangedEvent)) {
+            Config.readConfig(context).also { effect { logger.logDefaultDataSubRatConfig(it) } }
+        }
+    }
 
-    override val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>> =
+    override val defaultMobileIconMapping: State<Map<String, MobileIconGroup>> = buildState {
         defaultDataSubRatConfig
             .map { mobileMappingsProxy.mapIconSets(it) }
-            .distinctUntilChanged()
-            .onEach { logger.logDefaultMobileIconMapping(it) }
+            .apply { observe { logger.logDefaultMobileIconMapping(it) } }
+    }
 
-    override val defaultMobileIconGroup: Flow<MobileIconGroup> =
+    override val defaultMobileIconGroup: State<MobileIconGroup> = buildState {
         defaultDataSubRatConfig
             .map { mobileMappingsProxy.getDefaultIcons(it) }
-            .distinctUntilChanged()
-            .onEach { logger.logDefaultMobileIconGroup(it) }
+            .apply { observe { logger.logDefaultMobileIconGroup(it) } }
+    }
 
-    override val isAnySimSecure: Flow<Boolean> =
+    override val isAnySimSecure: State<Boolean> = buildState {
         conflatedCallbackFlow {
                 val callback =
                     object : KeyguardUpdateMonitorCallback() {
                         override fun onSimStateChanged(subId: Int, slotId: Int, simState: Int) {
                             logger.logOnSimStateChanged()
-                            trySend(getIsAnySimSecure())
+                            trySend(keyguardUpdateMonitor.isSimPinSecure)
                         }
                     }
                 keyguardUpdateMonitor.registerCallback(callback)
-                trySend(false)
                 awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
             }
             .flowOn(mainDispatcher)
-            .logDiffsForTable(
-                tableLogger,
-                LOGGING_PREFIX,
-                columnName = "isAnySimSecure",
-                initialValue = false,
-            )
-            .distinctUntilChanged()
+            .toState(false)
+            .also {
+                logDiffsForTable(it, tableLogger, LOGGING_PREFIX, columnName = "isAnySimSecure")
+            }
+    }
 
-    override fun getIsAnySimSecure() = keyguardUpdateMonitor.isSimPinSecure
+    private val defaultConnections: State<DefaultConnectionModel> = buildState {
+        connectivityRepository.defaultConnections.toState()
+    }
 
-    override fun getRepoForSubId(subId: Int): FullMobileConnectionRepository =
-        getOrCreateRepoForSubId(subId)
-
-    private fun getOrCreateRepoForSubId(subId: Int) =
-        subIdRepositoryCache[subId]?.get()
-            ?: createRepositoryForSubId(subId).also {
-                subIdRepositoryCache[subId] = WeakReference(it)
+    override val mobileIsDefault: State<Boolean> =
+        defaultConnections
+            .map { it.mobile.isDefault }
+            .also {
+                onActivated {
+                    logDiffsForTable(
+                        it,
+                        tableLogger,
+                        columnPrefix = LOGGING_PREFIX,
+                        columnName = "mobileIsDefault",
+                    )
+                }
             }
 
-    override val mobileIsDefault: StateFlow<Boolean> =
-        connectivityRepository.defaultConnections
-            .map { it.mobile.isDefault }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                columnPrefix = LOGGING_PREFIX,
-                columnName = "mobileIsDefault",
-                initialValue = false,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    override val hasCarrierMergedConnection: StateFlow<Boolean> =
+    override val hasCarrierMergedConnection: State<Boolean> =
         carrierMergedSubId
             .map { it != null }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                columnPrefix = LOGGING_PREFIX,
-                columnName = "hasCarrierMergedConnection",
-                initialValue = false,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+            .also {
+                onActivated {
+                    logDiffsForTable(
+                        it,
+                        tableLogger,
+                        columnPrefix = LOGGING_PREFIX,
+                        columnName = "hasCarrierMergedConnection",
+                    )
+                }
+            }
 
-    override val defaultConnectionIsValidated: StateFlow<Boolean> =
-        connectivityRepository.defaultConnections
+    override val defaultConnectionIsValidated: State<Boolean> =
+        defaultConnections
             .map { it.isValidated }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                tableLogger,
-                columnName = "defaultConnectionIsValidated",
-                initialValue = false,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+            .also {
+                onActivated {
+                    logDiffsForTable(
+                        it,
+                        tableLogger,
+                        columnPrefix = LOGGING_PREFIX,
+                        columnName = "defaultConnectionIsValidated",
+                    )
+                }
+            }
 
     /**
      * Flow that tracks the active mobile data subscriptions. Emits `true` whenever the active data
@@ -409,79 +429,45 @@
      * TODO(b/265164432): we should probably expose all change events, not just same group
      */
     @SuppressLint("MissingPermission")
-    override val activeSubChangedInGroupEvent =
-        activeMobileDataSubscriptionId
-            .pairwise()
-            .mapNotNull { (prevVal: Int?, newVal: Int?) ->
-                if (prevVal == null || newVal == null) return@mapNotNull null
-
-                val prevSub = subscriptionManager.getActiveSubscriptionInfo(prevVal)?.groupUuid
-                val nextSub = subscriptionManager.getActiveSubscriptionInfo(newVal)?.groupUuid
-
-                if (prevSub != null && prevSub == nextSub) Unit else null
+    override val activeSubChangedInGroupEvent: Events<Unit> = buildEvents {
+        activeMobileDataSubscriptionId.transitions
+            .mapNotNull { (prevVal, newVal) ->
+                prevVal?.let { newVal?.let { WithPrev(prevVal, newVal) } }
             }
-            .flowOn(bgDispatcher)
+            .mapAsyncLatest { (prevVal, newVal) ->
+                if (isActiveSubChangeInGroup(prevVal, newVal)) Unit else null
+            }
+            .filterNotNull()
+    }
 
-    override suspend fun isInEcmMode(): Boolean {
-        if (telephonyManager.emergencyCallbackMode) {
-            return true
+    private suspend fun isActiveSubChangeInGroup(prevId: Int, newId: Int): Boolean =
+        withContext(bgDispatcher) {
+            val prevSub = subscriptionManager.getActiveSubscriptionInfo(prevId)?.groupUuid
+            val nextSub = subscriptionManager.getActiveSubscriptionInfo(newId)?.groupUuid
+            prevSub != null && prevSub == nextSub
         }
-        return with(subscriptions.value) {
-            any { getOrCreateRepoForSubId(it.subscriptionId).isInEcmMode() }
-        }
-    }
 
-    private fun isValidSubId(subId: Int): Boolean = checkSub(subId, subscriptions.value)
+    private val isInEcmModeTopLevel: State<Boolean> =
+        telephonyManagerState.map { it.second.isNotEmpty() }
 
-    @VisibleForTesting fun getSubIdRepoCache() = subIdRepositoryCache
-
-    private fun subscriptionModelForSubId(subId: Int): Flow<SubscriptionModel?> {
-        return subscriptions.map { list ->
-            list.firstOrNull { model -> model.subscriptionId == subId }
-        }
-    }
-
-    private fun createRepositoryForSubId(subId: Int): FullMobileConnectionRepository {
-        return fullMobileRepoFactory.build(
-            subId,
-            isCarrierMerged(subId),
-            subscriptionModelForSubId(subId),
-            defaultNetworkName,
-            networkNameSeparator,
-        )
-    }
-
-    private fun updateRepos(newInfos: List<SubscriptionModel>) {
-        subIdRepositoryCache.forEach { (subId, repo) ->
-            repo.get()?.setIsCarrierMerged(isCarrierMerged(subId))
-        }
-    }
-
-    private fun isCarrierMerged(subId: Int): Boolean {
-        return subId == carrierMergedSubId.value
-    }
-
-    /**
-     * True if the checked subId is in the list of current subs or the active mobile data subId
-     *
-     * @param checkedSubs the list to validate [subId] against. To invalidate the cache, pass in the
-     *   new subscription list. Otherwise use [subscriptions.value] to validate a subId against the
-     *   current known subscriptions
-     */
-    private fun checkSub(subId: Int, checkedSubs: List<SubscriptionModel>): Boolean {
-        if (activeMobileDataSubscriptionId.value == subId) return true
-
-        checkedSubs.forEach {
-            if (it.subscriptionId == subId) {
-                return true
+    override val isInEcmMode: State<Boolean> =
+        isInEcmModeTopLevel.flatMap { isInEcm ->
+            if (isInEcm) {
+                stateOf(true)
+            } else {
+                mobileConnectionsBySubId.flatMap {
+                    it.mapValues { it.value.isInEcmMode }.combine().map { it.values.any { it } }
+                }
             }
         }
 
-        return false
-    }
+    /** Determines which subId is currently carrier-merged. */
+    val carrierMergedSelector: StateSelector<Int?> = carrierMergedSubId.selector()
 
-    private suspend fun fetchSubscriptionsList(): List<SubscriptionInfo> =
-        withContext(bgDispatcher) { subscriptionManager.completeActiveSubscriptionInfoList }
+    private suspend fun fetchSubscriptionModels(): List<SubscriptionModel> =
+        withContext(bgDispatcher) {
+            subscriptionManager.completeActiveSubscriptionInfoList.map { it.toSubscriptionModel() }
+        }
 
     private fun SubscriptionInfo.toSubscriptionModel(): SubscriptionModel =
         SubscriptionModel(
@@ -493,23 +479,106 @@
             profileClass = profileClass,
         )
 
+    private var dumpCache: DumpCache? = null
+
+    private data class DumpCache(val repos: Map<Int, FullMobileConnectionRepositoryKairos>)
+
     override fun dump(pw: PrintWriter, args: Array<String>) {
+        val cache = dumpCache ?: return
         val ipw = IndentingPrintWriter(pw, " ")
         ipw.println("Connection cache:")
 
         ipw.increaseIndent()
-        subIdRepositoryCache.entries.forEach { (subId, repo) ->
-            ipw.println("$subId: ${repo.get()}")
-        }
+        cache.repos.forEach { (subId, repo) -> ipw.println("$subId: $repo") }
         ipw.decreaseIndent()
 
-        ipw.println("Connections (${subIdRepositoryCache.size} total):")
+        ipw.println("Connections (${cache.repos.size} total):")
         ipw.increaseIndent()
-        subIdRepositoryCache.values.forEach { it.get()?.dump(ipw) }
+        cache.repos.values.forEach { it.dump(ipw) }
         ipw.decreaseIndent()
     }
 
+    fun interface ConnectionRepoFactory {
+        fun create(subId: Int): BuildSpec<MobileConnectionRepositoryKairos>
+    }
+
+    @dagger.Module
+    object Module {
+        @Provides
+        @ElementsIntoSet
+        fun kairosActivatable(
+            impl: Provider<MobileConnectionsRepositoryKairosImpl>
+        ): Set<@JvmSuppressWildcards KairosActivatable> =
+            if (Flags.statusBarMobileIconKairos()) setOf(impl.get()) else emptySet()
+    }
+
     companion object {
         private const val LOGGING_PREFIX = "Repo"
     }
 }
+
+@ExperimentalKairosApi
+class MobileConnectionRepositoryKairosFactoryImpl
+@Inject
+constructor(
+    context: Context,
+    private val connectionsRepo: MobileConnectionsRepositoryKairosImpl,
+    private val logFactory: TableLogBufferFactory,
+    private val carrierConfigRepo: CarrierConfigRepository,
+    private val telephonyManager: TelephonyManager,
+    private val mobileRepoFactory: MobileConnectionRepositoryKairosImpl.Factory,
+    private val mergedRepoFactory: CarrierMergedConnectionRepositoryKairos.Factory,
+) : MobileConnectionsRepositoryKairosImpl.ConnectionRepoFactory {
+
+    private val networkNameSeparator: String =
+        context.getString(R.string.status_bar_network_name_separator)
+
+    private val defaultNetworkName =
+        NetworkNameModel.Default(
+            context.getString(com.android.internal.R.string.lockscreen_carrier_default)
+        )
+
+    override fun create(subId: Int): BuildSpec<MobileConnectionRepositoryKairos> = buildSpec {
+        activated {
+            val mobileLogger =
+                logFactory.getOrCreate(tableBufferLogName(subId), MOBILE_CONNECTION_BUFFER_SIZE)
+            val mobileRepo = activated {
+                mobileRepoFactory.create(
+                    subId,
+                    mobileLogger,
+                    connectionsRepo.subscriptionsById.map { subs -> subs[subId] },
+                    defaultNetworkName,
+                    networkNameSeparator,
+                    carrierConfigRepo.getOrCreateConfigForSubId(subId),
+                    telephonyManager.createForSubscriptionId(subId),
+                )
+            }
+            FullMobileConnectionRepositoryKairos(
+                subId = subId,
+                tableLogBuffer = mobileLogger,
+                mobileRepo = mobileRepo,
+                carrierMergedRepoSpec =
+                    buildSpec {
+                        activated { mergedRepoFactory.build(subId, mobileLogger, mobileRepo) }
+                    },
+                isCarrierMerged = connectionsRepo.carrierMergedSelector[subId],
+            )
+        }
+    }
+
+    companion object {
+        /** The buffer size to use for logging. */
+        private const val MOBILE_CONNECTION_BUFFER_SIZE = 100
+
+        /** Returns a log buffer name for a mobile connection with the given [subId]. */
+        fun tableBufferLogName(subId: Int): String = "MobileConnectionLog[$subId]"
+    }
+
+    @dagger.Module
+    interface Module {
+        @Binds
+        fun bindImpl(
+            impl: MobileConnectionRepositoryKairosFactoryImpl
+        ): MobileConnectionsRepositoryKairosImpl.ConnectionRepoFactory
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Producer.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Producer.kt
new file mode 100644
index 0000000..a6209fa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Producer.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.kotlin
+
+/** Like a [javax.inject.Provider], but [get] is a `suspend fun`. */
+fun interface Producer<out T> {
+    suspend fun get(): T
+}
diff --git a/packages/SystemUI/tests/utils/src/android/net/ConnectivityManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/net/ConnectivityManagerKosmos.kt
new file mode 100644
index 0000000..516053d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/net/ConnectivityManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mockFixture
+
+var Kosmos.connectivityManager: ConnectivityManager by mockFixture()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kairos/CollectLastValue.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kairos/CollectLastValue.kt
new file mode 100644
index 0000000..927209f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kairos/CollectLastValue.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.kairos
+
+import com.android.systemui.coroutines.collectLastValue
+import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.KProperty
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+
+/**
+ * Collect [state] in a new [Job] and return a getter for the collection of values collected.
+ *
+ * ```
+ * fun myTest() = runTest {
+ *   // ...
+ *   val values by collectValues(underTest.flow)
+ *   assertThat(values).isEqualTo(listOf(expected1, expected2, ...))
+ * }
+ * ```
+ */
+@ExperimentalKairosApi
+fun <T> TestScope.collectLastValue(state: State<T>, kairosNetwork: KairosNetwork): KairosValue<T?> {
+    var value: T? = null
+    backgroundScope.launch { kairosNetwork.activateSpec { state.observe { value = it } } }
+    return KairosValueImpl {
+        runCurrent()
+        value
+    }
+}
+
+/**
+ * Collect [flow] in a new [Job] and return a getter for the collection of values collected.
+ *
+ * ```
+ * fun myTest() = runTest {
+ *   // ...
+ *   val values by collectValues(underTest.flow)
+ *   assertThat(values).isEqualTo(listOf(expected1, expected2, ...))
+ * }
+ * ```
+ */
+@ExperimentalKairosApi
+fun <T> TestScope.collectLastValue(flow: Events<T>, kairosNetwork: KairosNetwork): KairosValue<T?> {
+    var value: T? = null
+    backgroundScope.launch { kairosNetwork.activateSpec { flow.observe { value = it } } }
+    return KairosValueImpl {
+        runCurrent()
+        value
+    }
+}
+
+/**
+ * Collect [flow] in a new [Job] and return a getter for the collection of values collected.
+ *
+ * ```
+ * fun myTest() = runTest {
+ *   // ...
+ *   val values by collectValues(underTest.flow)
+ *   assertThat(values).isEqualTo(listOf(expected1, expected2, ...))
+ * }
+ * ```
+ */
+@ExperimentalKairosApi
+fun <T> TestScope.collectValues(
+    flow: Events<T>,
+    kairosNetwork: KairosNetwork,
+): KairosValue<List<T>> {
+    val values = mutableListOf<T>()
+    backgroundScope.launch { kairosNetwork.activateSpec { flow.observe { values.add(it) } } }
+    return KairosValueImpl {
+        runCurrent()
+        values.toList()
+    }
+}
+
+/** @see collectLastValue */
+interface KairosValue<T> : ReadOnlyProperty<Any?, T> {
+    val value: T
+}
+
+private class KairosValueImpl<T>(private val block: () -> T) : KairosValue<T> {
+    override val value: T
+        get() = block()
+
+    override fun getValue(thisRef: Any?, property: KProperty<*>): T = value
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kairos/KairosKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kairos/KairosKosmos.kt
new file mode 100644
index 0000000..d7f2041
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kairos/KairosKosmos.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.kairos
+
+import com.android.systemui.KairosActivatable
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+
+@ExperimentalKairosApi
+val Kosmos.kairos: KairosNetwork by Fixture { applicationCoroutineScope.launchKairosNetwork() }
+
+@ExperimentalKairosApi
+fun Kosmos.activateKairosActivatable(activatable: KairosActivatable) {
+    applicationCoroutineScope.launch { kairos.activateSpec { activatable.run { activate() } } }
+}
+
+@ExperimentalKairosApi
+fun <T : KairosActivatable> ActivatedKairosFixture(block: Kosmos.() -> T) = Fixture {
+    block().also { activateKairosActivatable(it) }
+}
+
+@ExperimentalKairosApi
+fun Kosmos.runKairosTest(timeout: Duration = 5.seconds, block: suspend KairosTestScope.() -> Unit) =
+    testScope.runTest(timeout) { KairosTestScopeImpl(this@runKairosTest, this, kairos).block() }
+
+@ExperimentalKairosApi
+interface KairosTestScope : Kosmos {
+    fun <T> State<T>.collectLastValue(): KairosValue<T?>
+
+    suspend fun <T> State<T>.sample(): T
+
+    fun <T : KairosActivatable> T.activated(): T
+}
+
+@ExperimentalKairosApi
+private class KairosTestScopeImpl(
+    kosmos: Kosmos,
+    val testScope: TestScope,
+    val kairos: KairosNetwork,
+) : KairosTestScope, Kosmos by kosmos {
+    override fun <T> State<T>.collectLastValue(): KairosValue<T?> =
+        testScope.collectLastValue(this@collectLastValue, kairos)
+
+    override suspend fun <T> State<T>.sample(): T = kairos.transact { sample() }
+
+    override fun <T : KairosActivatable> T.activated(): T =
+        this.also { activateKairosActivatable(it) }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepositoryKairos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepositoryKairos.kt
new file mode 100644
index 0000000..8cf3ee8
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepositoryKairos.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository
+
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosNetwork
+import com.android.systemui.kairos.MutableState
+import com.android.systemui.kairos.State
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository.Companion.DEFAULT_NETWORK_NAME
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+
+@ExperimentalKairosApi
+class FakeMobileConnectionRepositoryKairos(
+    override val subId: Int,
+    kairos: KairosNetwork,
+    override val tableLogBuffer: TableLogBuffer,
+) : MobileConnectionRepositoryKairos {
+    override val carrierId = MutableState(kairos, 0)
+    override val inflateSignalStrength = MutableState(kairos, false)
+    override val allowNetworkSliceIndicator = MutableState(kairos, true)
+    override val isEmergencyOnly = MutableState(kairos, false)
+    override val isRoaming = MutableState(kairos, false)
+    override val operatorAlphaShort = MutableState<String?>(kairos, null)
+    override val isInService = MutableState(kairos, false)
+    override val isNonTerrestrial = MutableState(kairos, false)
+    override val isGsm = MutableState(kairos, false)
+    override val cdmaLevel = MutableState(kairos, 0)
+    override val primaryLevel = MutableState(kairos, 0)
+    override val satelliteLevel = MutableState(kairos, 0)
+    override val dataConnectionState = MutableState(kairos, DataConnectionState.Disconnected)
+    override val dataActivityDirection =
+        MutableState(kairos, DataActivityModel(hasActivityIn = false, hasActivityOut = false))
+    override val carrierNetworkChangeActive = MutableState(kairos, false)
+    override val resolvedNetworkType =
+        MutableState<ResolvedNetworkType>(kairos, ResolvedNetworkType.UnknownNetworkType)
+    override val numberOfLevels = MutableState(kairos, DEFAULT_NUM_LEVELS)
+    override val dataEnabled = MutableState(kairos, true)
+    override val cdmaRoaming = MutableState(kairos, false)
+    override val networkName =
+        MutableState<NetworkNameModel>(kairos, NetworkNameModel.Default(DEFAULT_NETWORK_NAME))
+    override val carrierName =
+        MutableState<NetworkNameModel>(kairos, NetworkNameModel.Default(DEFAULT_NETWORK_NAME))
+    override val isAllowedDuringAirplaneMode = MutableState(kairos, false)
+    override val hasPrioritizedNetworkCapabilities = MutableState(kairos, false)
+    override val isInEcmMode: State<Boolean> = MutableState(kairos, false)
+
+    /**
+     * Set [primaryLevel] and [cdmaLevel]. Convenient when you don't care about the connection type
+     */
+    fun setAllLevels(level: Int) {
+        cdmaLevel.setValue(level)
+        primaryLevel.setValue(level)
+    }
+
+    /** Set the correct [resolvedNetworkType] for the given group via its lookup key */
+    fun setNetworkTypeKey(key: String) {
+        resolvedNetworkType.setValue(ResolvedNetworkType.DefaultNetworkType(key))
+    }
+
+    /**
+     * Set both [isRoaming] and [cdmaRoaming] properties, in the event that you don't care about the
+     * connection type
+     */
+    fun setAllRoaming(roaming: Boolean) {
+        isRoaming.setValue(roaming)
+        cdmaRoaming.setValue(roaming)
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepositoryKairos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepositoryKairos.kt
new file mode 100644
index 0000000..624b2cc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepositoryKairos.kt
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository
+
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import android.telephony.TelephonyDisplayInfo
+import android.telephony.TelephonyManager
+import com.android.settingslib.SignalIcon
+import com.android.settingslib.mobile.MobileMappings
+import com.android.settingslib.mobile.TelephonyIcons
+import com.android.systemui.KairosBuilder
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosNetwork
+import com.android.systemui.kairos.MutableEvents
+import com.android.systemui.kairos.MutableState
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.asIncremental
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapValues
+import com.android.systemui.kairosBuilder
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
+import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
+
+// TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionsRepositoryKairos
+@ExperimentalKairosApi
+class FakeMobileConnectionsRepositoryKairos(
+    kairos: KairosNetwork,
+    val tableLogBuffer: TableLogBuffer,
+    mobileMappings: MobileMappingsProxy = FakeMobileMappingsProxy(),
+) : MobileConnectionsRepositoryKairos, KairosBuilder by kairosBuilder() {
+
+    val GSM_KEY = mobileMappings.toIconKey(GSM)
+    val LTE_KEY = mobileMappings.toIconKey(LTE)
+    val UMTS_KEY = mobileMappings.toIconKey(UMTS)
+    val LTE_ADVANCED_KEY = mobileMappings.toIconKeyOverride(LTE_ADVANCED_PRO)
+
+    /**
+     * To avoid a reliance on [MobileMappings], we'll build a simpler map from network type to
+     * mobile icon. See TelephonyManager.NETWORK_TYPES for a list of types and [TelephonyIcons] for
+     * the exhaustive set of icons
+     */
+    val TEST_MAPPING: Map<String, SignalIcon.MobileIconGroup> =
+        mapOf(
+            GSM_KEY to TelephonyIcons.THREE_G,
+            LTE_KEY to TelephonyIcons.LTE,
+            UMTS_KEY to TelephonyIcons.FOUR_G,
+            LTE_ADVANCED_KEY to TelephonyIcons.NR_5G,
+        )
+
+    override val subscriptions = MutableState(kairos, emptyList<SubscriptionModel>())
+
+    override val mobileConnectionsBySubId = buildIncremental {
+        subscriptions
+            .map { it.associate { sub -> sub.subscriptionId to Unit } }
+            .asIncremental()
+            .mapValues { (subId, _) ->
+                buildSpec {
+                    FakeMobileConnectionRepositoryKairos(subId, kairosNetwork, tableLogBuffer)
+                }
+            }
+            .applyLatestSpecForKey()
+    }
+
+    private val _activeMobileDataSubscriptionId = MutableState<Int?>(kairos, null)
+    override val activeMobileDataSubscriptionId: State<Int?> = _activeMobileDataSubscriptionId
+
+    override val activeMobileDataRepository: State<MobileConnectionRepositoryKairos?> =
+        combine(mobileConnectionsBySubId, activeMobileDataSubscriptionId) { conns, activeSub ->
+            conns[activeSub]
+        }
+
+    override val activeSubChangedInGroupEvent = MutableEvents<Unit>(kairos)
+
+    override val defaultDataSubId = MutableState(kairos, INVALID_SUBSCRIPTION_ID)
+
+    override val mobileIsDefault = MutableState(kairos, false)
+
+    override val hasCarrierMergedConnection = MutableState(kairos, false)
+
+    override val defaultConnectionIsValidated = MutableState(kairos, false)
+
+    override val defaultDataSubRatConfig = MutableState(kairos, MobileMappings.Config())
+
+    override val defaultMobileIconMapping = MutableState(kairos, TEST_MAPPING)
+
+    override val defaultMobileIconGroup = MutableState(kairos, DEFAULT_ICON)
+
+    override val isDeviceEmergencyCallCapable = MutableState(kairos, false)
+
+    override val isAnySimSecure = MutableState(kairos, false)
+
+    override val isInEcmMode: State<Boolean> = MutableState(kairos, false)
+
+    fun setActiveMobileDataSubscriptionId(subId: Int) {
+        // Simulate the filtering that the repo does
+        if (subId == INVALID_SUBSCRIPTION_ID) {
+            _activeMobileDataSubscriptionId.setValue(null)
+        } else {
+            _activeMobileDataSubscriptionId.setValue(subId)
+        }
+    }
+
+    companion object {
+        val DEFAULT_ICON = TelephonyIcons.G
+
+        // Use [MobileMappings] to define some simple definitions
+        const val GSM = TelephonyManager.NETWORK_TYPE_GSM
+        const val LTE = TelephonyManager.NETWORK_TYPE_LTE
+        const val UMTS = TelephonyManager.NETWORK_TYPE_UMTS
+        const val LTE_ADVANCED_PRO = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO
+    }
+}
+
+@ExperimentalKairosApi
+val MobileConnectionsRepositoryKairos.fake
+    get() = this as FakeMobileConnectionsRepositoryKairos
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileDataRepositoryKairosKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileDataRepositoryKairosKosmos.kt
new file mode 100644
index 0000000..f57cf99
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileDataRepositoryKairosKosmos.kt
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository
+
+import android.content.applicationContext
+import android.telephony.SubscriptionManager
+import android.telephony.telephonyManager
+import com.android.keyguard.keyguardUpdateMonitor
+import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.demoModeController
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosNetwork
+import com.android.systemui.kairos.MutableEvents
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logcatTableLogBuffer
+import com.android.systemui.log.table.tableLogBufferFactory
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.airplaneModeRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoModeMobileConnectionDataSourceKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryKairosImpl
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
+import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy
+import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.wifiRepository
+import com.android.systemui.util.mockito.mockFixture
+import org.mockito.kotlin.mock
+
+@ExperimentalKairosApi
+var Kosmos.mobileConnectionsRepositoryKairos: MobileConnectionsRepositoryKairos by Fixture {
+    mobileRepositorySwitcherKairos
+}
+
+@ExperimentalKairosApi
+val Kosmos.fakeMobileConnectionsRepositoryKairos by ActivatedKairosFixture {
+    FakeMobileConnectionsRepositoryKairos(kairos, logcatTableLogBuffer(this), mobileMappingsProxy)
+}
+
+@ExperimentalKairosApi
+val Kosmos.demoMobileConnectionsRepositoryKairos by ActivatedKairosFixture {
+    DemoMobileConnectionsRepositoryKairos(
+        mobileDataSource = demoModeMobileConnectionDataSourceKairos,
+        wifiDataSource = wifiDataSource,
+        context = applicationContext,
+        logFactory = tableLogBufferFactory,
+    )
+}
+
+@ExperimentalKairosApi
+val Kosmos.demoModeMobileConnectionDataSourceKairos:
+    DemoModeMobileConnectionDataSourceKairos by Fixture {
+    FakeDemoModeMobileConnectionDataSourceKairos(kairos)
+}
+
+val Kosmos.wifiDataSource: DemoModeWifiDataSource by mockFixture()
+
+@ExperimentalKairosApi
+class FakeDemoModeMobileConnectionDataSourceKairos(kairos: KairosNetwork) :
+    DemoModeMobileConnectionDataSourceKairos {
+    override val mobileEvents = MutableEvents<FakeNetworkEventModel?>(kairos)
+}
+
+@ExperimentalKairosApi
+val DemoModeMobileConnectionDataSourceKairos.fake
+    get() = this as FakeDemoModeMobileConnectionDataSourceKairos
+
+@ExperimentalKairosApi
+val Kosmos.mobileRepositorySwitcherKairos:
+    MobileRepositorySwitcherKairos by ActivatedKairosFixture {
+    MobileRepositorySwitcherKairos(
+        realRepository = mobileConnectionsRepositoryKairosImpl,
+        demoRepositoryFactory = demoMobileConnectionsRepositoryKairosFactory,
+        demoModeController = demoModeController,
+    )
+}
+
+@ExperimentalKairosApi
+val Kosmos.demoMobileConnectionsRepositoryKairosFactory:
+    DemoMobileConnectionsRepositoryKairos.Factory by Fixture {
+    DemoMobileConnectionsRepositoryKairos.Factory {
+        DemoMobileConnectionsRepositoryKairos(
+            mobileDataSource = demoModeMobileConnectionDataSourceKairos,
+            wifiDataSource = wifiDataSource,
+            context = applicationContext,
+            logFactory = tableLogBufferFactory,
+        )
+    }
+}
+
+@ExperimentalKairosApi
+val Kosmos.mobileConnectionsRepositoryKairosImpl:
+    MobileConnectionsRepositoryKairosImpl by ActivatedKairosFixture {
+    MobileConnectionsRepositoryKairosImpl(
+        connectivityRepository = connectivityRepository,
+        subscriptionManager = subscriptionManager,
+        subscriptionManagerProxy = subscriptionManagerProxy,
+        telephonyManager = telephonyManager,
+        logger = mobileInputLogger,
+        tableLogger = summaryLogger,
+        mobileMappingsProxy = mobileMappingsProxy,
+        broadcastDispatcher = broadcastDispatcher,
+        context = applicationContext,
+        bgDispatcher = testDispatcher,
+        mainDispatcher = testDispatcher,
+        airplaneModeRepository = airplaneModeRepository,
+        wifiRepository = wifiRepository,
+        keyguardUpdateMonitor = keyguardUpdateMonitor,
+        dumpManager = dumpManager,
+        mobileRepoFactory = { mobileConnectionRepositoryKairosFactory },
+    )
+}
+
+val Kosmos.subscriptionManager: SubscriptionManager by mockFixture()
+val Kosmos.mobileInputLogger: MobileInputLogger by mockFixture()
+val Kosmos.summaryLogger: TableLogBuffer by Fixture { logcatTableLogBuffer(this, "summaryLogger") }
+
+@ExperimentalKairosApi
+val Kosmos.mobileConnectionRepositoryKairosFactory by Fixture {
+    MobileConnectionsRepositoryKairosImpl.ConnectionRepoFactory { subId ->
+        buildSpec { FakeMobileConnectionRepositoryKairos(subId, kairos, mock()) }
+    }
+}
+
+val Kosmos.subscriptionManagerProxy: SubscriptionManagerProxy by Fixture {
+    FakeSubscriptionManagerProxy()
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
index 5b70907..a391c44 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
@@ -41,3 +41,6 @@
             SubscriptionInfo.Builder().setId(subId).setEmbedded(isEmbedded).build()
     }
 }
+
+val SubscriptionManagerProxy.fake
+    get() = this as FakeSubscriptionManagerProxy
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryKosmos.kt
index 00bfa99..bb254a1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryKosmos.kt
@@ -18,5 +18,5 @@
 
 import com.android.systemui.kosmos.Kosmos
 
-val Kosmos.connectivityRepository: ConnectivityRepository by
+var Kosmos.connectivityRepository: ConnectivityRepository by
     Kosmos.Fixture { FakeConnectivityRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryKosmos.kt
index e44061a..f560c50 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryKosmos.kt
@@ -19,4 +19,4 @@
 import com.android.systemui.kosmos.Kosmos
 
 val Kosmos.fakeWifiRepository: FakeWifiRepository by Kosmos.Fixture { FakeWifiRepository() }
-val Kosmos.wifiRepository: WifiRepository by Kosmos.Fixture { fakeWifiRepository }
+var Kosmos.wifiRepository: WifiRepository by Kosmos.Fixture { fakeWifiRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/MockitoKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/MockitoKosmos.kt
new file mode 100644
index 0000000..1638cb7
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/MockitoKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.mockito
+
+import com.android.systemui.kosmos.Kosmos.Fixture
+import org.mockito.kotlin.mock
+
+inline fun <reified T> mockFixture(): Fixture<T> = Fixture { mock() }
