[kairos] Kairos in Mobile Pipeline data layer

Flag: com.android.systemui.status_bar_mobile_icon_kairos
Bug: 383172066
Test: atest
Change-Id: I6f5e921609e4b482bffaf2d63c202d680a94bcef
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() }