Add OngoingCallInteractor

This CL removes dependency on OngoingCallController by introducing OngoingCallInteractor as the source of truth for ongoing call state.

The interactor:
Reads call notifications from ActiveNotificationsInteractor
Tracks call app visibility through ActivityManagerRepository
Emits ongoing call state through a Flow to CallChipInteractor


Bug:b/372657935
Flag: com.android.systemui.status_bar_chips_modernization

Change-Id: Ifd5ae9c3e566b99f268201f03db092850923eee6
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 20b83e1..9fda653 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -434,6 +434,18 @@
     }
 }
 
+
+flag {
+    name: "status_bar_chips_modernization"
+    namespace: "systemui"
+    description: "Deprecate OngoingCallController and implement OngoingActivityChips"
+    "in compose"
+    bug: "372657935"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
 flag {
     name: "status_bar_use_repos_for_call_chip"
     namespace: "systemui"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
index 110dec6..f76ee5e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
@@ -87,7 +87,7 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 @OptIn(ExperimentalCoroutinesApi::class)
-@DisableFlags(FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP)
+@DisableFlags(FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP, StatusBarChipsModernization.FLAG_NAME)
 class OngoingCallControllerViaListenerTest : SysuiTestCase() {
     private val kosmos = Kosmos()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
index 2ad50cc..647b5f8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
@@ -29,6 +29,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CHIPS_MODERNIZATION
 import com.android.systemui.Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS
 import com.android.systemui.Flags.FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP
 import com.android.systemui.SysuiTestCase
@@ -77,6 +78,7 @@
 @TestableLooper.RunWithLooper
 @OptIn(ExperimentalCoroutinesApi::class)
 @EnableFlags(FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP)
+@DisableFlags(StatusBarChipsModernization.FLAG_NAME)
 class OngoingCallControllerViaRepoTest : SysuiTestCase() {
     private val kosmos = Kosmos()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
index 4c6eaa5..a446313 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
@@ -16,10 +16,13 @@
 
 package com.android.systemui.statusbar.phone.ongoingcall.data.repository
 
+import android.platform.test.annotations.DisableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_STATUS_BAR_CHIPS_MODERNIZATION
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
 import com.google.common.truth.Truth.assertThat
@@ -28,6 +31,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@DisableFlags(StatusBarChipsModernization.FLAG_NAME)
 class OngoingCallRepositoryTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val underTest = kosmos.ongoingCallRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
new file mode 100644
index 0000000..ca1413e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
@@ -0,0 +1,208 @@
+/*
+ * 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.statusbar.phone.ongoingcall.domain.interactor
+
+import android.app.PendingIntent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.data.repository.activityManagerRepository
+import com.android.systemui.activity.data.repository.fake
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
+import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
+import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.shared.CallType
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class OngoingCallInteractorTest : SysuiTestCase() {
+    private val kosmos = Kosmos().useUnconfinedTestDispatcher()
+    private val repository = kosmos.activeNotificationListRepository
+    private val underTest = kosmos.ongoingCallInteractor
+
+    @Test
+    fun noNotification_emitsNoCall() = runTest {
+        val state by collectLastValue(underTest.ongoingCallState)
+        assertThat(state).isInstanceOf(OngoingCallModel.NoCall::class.java)
+    }
+
+    @Test
+    fun ongoingCallNotification_setsNotificationIconAndIntent() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.ongoingCallState)
+
+            // Set up notification with icon view and intent
+            val testIconView: StatusBarIconView = mock()
+            val testIntent: PendingIntent = mock()
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
+                                statusBarChipIcon = testIconView,
+                                contentIntent = testIntent
+                            )
+                        )
+                    }
+                    .build()
+
+            // Verify model is InCall and has the correct icon and intent.
+            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
+            val model = latest as OngoingCallModel.InCall
+            assertThat(model.notificationIconView).isSameInstanceAs(testIconView)
+            assertThat(model.intent).isSameInstanceAs(testIntent)
+        }
+
+    @Test
+    fun ongoingCallNotification_emitsInCall() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.ongoingCallState)
+
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1", whenTime = 1000L, callType = CallType.Ongoing
+                            )
+                        )
+                    }
+                    .build()
+
+            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
+        }
+
+    @Test
+    fun notificationRemoved_emitsNoCall() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.ongoingCallState)
+
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1", whenTime = 1000L, callType = CallType.Ongoing
+                            )
+                        )
+                    }
+                    .build()
+
+            repository.activeNotifications.value = ActiveNotificationsStore()
+            assertThat(latest).isInstanceOf(OngoingCallModel.NoCall::class.java)
+        }
+
+    @Test
+    fun ongoingCallNotification_appVisibleInitially_emitsInCallWithVisibleApp() =
+        kosmos.runTest {
+            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = true
+            val latest by collectLastValue(underTest.ongoingCallState)
+
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
+                                uid = UID
+                            )
+                        )
+                    }
+                    .build()
+
+            assertThat(latest).isInstanceOf(OngoingCallModel.InCallWithVisibleApp::class.java)
+        }
+
+    @Test
+    fun ongoingCallNotification_appNotVisibleInitially_emitsInCall() =
+        kosmos.runTest {
+            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = false
+            val latest by collectLastValue(underTest.ongoingCallState)
+
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
+                                uid = UID
+                            )
+                        )
+                    }
+                    .build()
+
+            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
+        }
+
+    @Test
+    fun ongoingCallNotification_visibilityChanges_updatesState() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.ongoingCallState)
+
+            // Start with notification and app not visible
+            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = false
+            repository.activeNotifications.value =
+                ActiveNotificationsStore.Builder()
+                    .apply {
+                        addIndividualNotif(
+                            activeNotificationModel(
+                                key = "notif1",
+                                whenTime = 1000L,
+                                callType = CallType.Ongoing,
+                                uid = UID
+                            )
+                        )
+                    }
+                    .build()
+            assertThat(latest)
+                .isInstanceOf(OngoingCallModel.InCall::class.java)
+
+            // App becomes visible
+            kosmos.activityManagerRepository.fake.setIsAppVisible(UID, true)
+            assertThat(latest).isInstanceOf(OngoingCallModel.InCallWithVisibleApp::class.java)
+
+            // App becomes invisible again
+            kosmos.activityManagerRepository.fake.setIsAppVisible(UID, false)
+            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
+        }
+
+    companion object {
+        private const val UID = 885
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
index bb0467f..2eae3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
@@ -23,6 +23,8 @@
 import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad
 import com.android.systemui.statusbar.chips.StatusBarChipsLog
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.OngoingCallRepository
+import com.android.systemui.statusbar.phone.ongoingcall.domain.interactor.OngoingCallInteractor
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -37,17 +39,30 @@
 @Inject
 constructor(
     @Application private val scope: CoroutineScope,
+    ongoingCallInteractor: OngoingCallInteractor,
     repository: OngoingCallRepository,
     @StatusBarChipsLog private val logger: LogBuffer,
 ) {
     val ongoingCallState: StateFlow<OngoingCallModel> =
-        repository.ongoingCallState
+        (if (StatusBarChipsModernization.isEnabled)
+            ongoingCallInteractor.ongoingCallState
+        else
+            repository.ongoingCallState)
             .onEach {
-                logger.log(TAG, LogLevel.INFO, { str1 = it::class.simpleName }, { "State: $str1" })
+                logger.log(
+                    TAG,
+                    LogLevel.INFO,
+                    { str1 = it::class.simpleName },
+                    { "State: $str1" }
+                )
             }
-            .stateIn(scope, SharingStarted.Lazily, OngoingCallModel.NoCall)
+            .stateIn(
+                scope,
+                SharingStarted.Lazily,
+                OngoingCallModel.NoCall
+            )
 
     companion object {
         private val TAG = "OngoingCall".pad()
     }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index b8cdd25..6f491e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -59,7 +59,8 @@
         interactor.ongoingCallState
             .map { state ->
                 when (state) {
-                    is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden()
+                    is OngoingCallModel.NoCall,
+                    is OngoingCallModel.InCallWithVisibleApp -> OngoingActivityChipModel.Hidden()
                     is OngoingCallModel.InCall -> {
                         val icon =
                             if (
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
index 47b695e..2588c7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallLog
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.ui.SystemBarUtilsProxyImpl
 import com.android.systemui.statusbar.window.MultiDisplayStatusBarWindowControllerStore
@@ -63,11 +64,6 @@
 
     @Binds
     @IntoMap
-    @ClassKey(OngoingCallController::class)
-    fun bindOngoingCallController(impl: OngoingCallController): CoreStartable
-
-    @Binds
-    @IntoMap
     @ClassKey(LightBarController::class)
     fun lightBarControllerAsCoreStartable(controller: LightBarController): CoreStartable
 
@@ -90,6 +86,18 @@
     ): LightBarController.Factory
 
     companion object {
+        @Provides
+        @SysUISingleton
+        @IntoMap
+        @ClassKey(OngoingCallController::class)
+        fun ongoingCallController(
+            controller: OngoingCallController
+        ): CoreStartable =
+            if (StatusBarChipsModernization.isEnabled) {
+                CoreStartable.NOP
+            } else {
+                controller
+            }
 
         @Provides
         @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 23b4b65..70e1b90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -71,6 +71,7 @@
 import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarComponent.Startable;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization;
 import com.android.systemui.statusbar.phone.ui.DarkIconManager;
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarViewBinder;
@@ -965,7 +966,9 @@
             mOngoingCallController.addCallback(mOngoingCallListener);
         }
         // TODO(b/364653005): Do we also need to set the secondary activity chip?
-        mOngoingCallController.setChipView(mPrimaryOngoingActivityChip);
+        if (!StatusBarChipsModernization.isEnabled()) {
+            mOngoingCallController.setChipView(mPrimaryOngoingActivityChip);
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 78926c7..2166304 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -60,7 +60,10 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 
-/** A controller to handle the ongoing call chip in the collapsed status bar. */
+/** A controller to handle the ongoing call chip in the collapsed status bar.
+ * @deprecated Use [OngoingCallInteractor] instead, which follows recommended architecture patterns
+ */
+@Deprecated("Use OngoingCallInteractor instead")
 @SysUISingleton
 class OngoingCallController
 @Inject
@@ -165,6 +168,9 @@
         }
 
     override fun start() {
+        if (StatusBarChipsModernization.isEnabled)
+            return
+
         dumpManager.registerDumpable(this)
 
         if (Flags.statusBarUseReposForCallChip()) {
@@ -201,6 +207,8 @@
      * [com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment].
      */
     fun setChipView(chipView: View) {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         tearDownChipView()
         this.chipView = chipView
         val backgroundView: ChipBackgroundContainer? =
@@ -217,6 +225,8 @@
      * Returns true if there's an active ongoing call that should be displayed in a status bar chip.
      */
     fun hasOngoingCall(): Boolean {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         return callNotificationInfo?.isOngoing == true &&
             // When the user is in the phone app, don't show the chip.
             !uidObserver.isCallAppVisible
@@ -224,6 +234,8 @@
 
     /** Creates the right [OngoingCallModel] based on the call state. */
     private fun getOngoingCallModel(): OngoingCallModel {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         if (hasOngoingCall()) {
             val currentInfo =
                 callNotificationInfo
@@ -255,6 +267,8 @@
     }
 
     override fun addCallback(listener: OngoingCallListener) {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         synchronized(mListeners) {
             if (!mListeners.contains(listener)) {
                 mListeners.add(listener)
@@ -263,10 +277,14 @@
     }
 
     override fun removeCallback(listener: OngoingCallListener) {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         synchronized(mListeners) { mListeners.remove(listener) }
     }
 
     private fun updateInfoFromNotifModel(notifModel: ActiveNotificationModel?) {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         if (notifModel == null) {
             logger.log(TAG, LogLevel.DEBUG, {}, { "NotifInteractorCallModel: null" })
             removeChip()
@@ -310,6 +328,8 @@
     }
 
     private fun updateChip() {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         val currentCallNotificationInfo = callNotificationInfo ?: return
 
         val currentChipView = chipView
@@ -360,6 +380,8 @@
     }
 
     private fun updateChipClickListener() {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         if (Flags.statusBarScreenSharingChips()) {
             return
         }
@@ -386,10 +408,14 @@
 
     /** Returns true if the given [procState] represents a process that's visible to the user. */
     private fun isProcessVisibleToUser(procState: Int): Boolean {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         return procState <= ActivityManager.PROCESS_STATE_TOP
     }
 
     private fun updateGestureListening() {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         if (
             callNotificationInfo == null ||
                 callNotificationInfo?.statusBarSwipedAway == true ||
@@ -404,6 +430,8 @@
     }
 
     private fun removeChip() {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         callNotificationInfo = null
         if (!Flags.statusBarScreenSharingChips()) {
             tearDownChipView()
@@ -432,6 +460,8 @@
      * detected.
      */
     private fun onSwipeAwayGestureDetected() {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         logger.log(TAG, LogLevel.DEBUG, {}, { "Swipe away gesture detected" })
         callNotificationInfo = callNotificationInfo?.copy(statusBarSwipedAway = true)
         statusBarWindowControllerStore.defaultDisplay.setOngoingProcessRequiresStatusBarVisible(
@@ -441,6 +471,8 @@
     }
 
     private fun sendStateChangeEvent() {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         ongoingCallRepository.setOngoingCallState(getOngoingCallModel())
         mListeners.forEach { l -> l.onOngoingCallStateChanged(animate = true) }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
new file mode 100644
index 0000000..2ab2b68
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt
@@ -0,0 +1,52 @@
+/*
+* 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.phone.ongoingcall
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the status_bar_use_interactor_for_call_chip flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object StatusBarChipsModernization {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_STATUS_BAR_CHIPS_MODERNIZATION
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the refactor enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.statusBarChipsModernization() && Flags.statusBarRootModernization()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepository.kt
index f16371a..b932c71a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepository.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallLog
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -33,7 +34,9 @@
  * [com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController] and
  * [com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore]. Instead, those two
  * classes both refer to this repository.
+ * @deprecated Use [OngoingCallInteractor] instead.
  */
+@Deprecated("Use OngoingCallInteractor instead")
 @SysUISingleton
 class OngoingCallRepository
 @Inject
@@ -49,6 +52,8 @@
      * [com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController].
      */
     fun setOngoingCallState(state: OngoingCallModel) {
+        StatusBarChipsModernization.assertInLegacyMode()
+
         logger.log(
             TAG,
             LogLevel.DEBUG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
new file mode 100644
index 0000000..1f7bd14
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.phone.ongoingcall.domain.interactor
+
+import com.android.systemui.activity.data.repository.ActivityManagerRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.Logger
+import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
+import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallLog
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Interactor for determining whether to show a chip in the status bar for ongoing phone calls.
+ *
+ * This class monitors call notifications and the visibility of call apps to determine the appropriate
+ * chip state. It emits:
+ *  * - [OngoingCallModel.NoCall] when there is no call notification
+ *  * - [OngoingCallModel.InCallWithVisibleApp] when there is a call notification but the call app is visible
+ *  * - [OngoingCallModel.InCall] when there is a call notification and the call app is not visible
+ *  */
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class OngoingCallInteractor @Inject constructor(
+    @Application private val scope: CoroutineScope,
+    activityManagerRepository: ActivityManagerRepository,
+    activeNotificationsInteractor: ActiveNotificationsInteractor,
+    @OngoingCallLog private val logBuffer: LogBuffer,
+) {
+    private val logger = Logger(logBuffer, TAG)
+
+    /**
+     * The current state of ongoing calls.
+     */
+    val ongoingCallState: StateFlow<OngoingCallModel> =
+        activeNotificationsInteractor.ongoingCallNotification
+            .flatMapLatest { notificationModel ->
+                when (notificationModel) {
+                    null -> {
+                        logger.d("No active call notification - hiding chip")
+                        flowOf(OngoingCallModel.NoCall)
+                    }
+
+                    else -> combine(
+                        flowOf(notificationModel),
+                        activityManagerRepository.createIsAppVisibleFlow(
+                            creationUid = notificationModel.uid,
+                            logger = logger,
+                            identifyingLogTag = TAG,
+                        ),
+                    ) { model, isVisible ->
+                        when {
+                            isVisible -> {
+                                logger.d({ "Call app is visible: uid=$int1" }) {
+                                    int1 = model.uid
+                                }
+                                OngoingCallModel.InCallWithVisibleApp
+                            }
+
+                            else -> {
+                                logger.d({ "Active call detected: startTime=$long1 hasIcon=$bool1" }) {
+                                    long1 = model.whenTime
+                                    bool1 = model.statusBarChipIconView != null
+                                }
+                                OngoingCallModel.InCall(
+                                    startTimeMs = model.whenTime,
+                                    notificationIconView = model.statusBarChipIconView,
+                                    intent = model.contentIntent,
+                                )
+                            }
+                        }
+                    }
+                }
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingCallModel.NoCall)
+
+    companion object {
+        private val TAG = "OngoingCall"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index 34bff80..c2c91b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -25,6 +25,12 @@
     data object NoCall : OngoingCallModel
 
     /**
+     * There is an ongoing call but the call app is currently visible, so we don't need to show
+     * the chip.
+     */
+    data object InCallWithVisibleApp : OngoingCallModel
+
+    /**
      * There *is* an ongoing call.
      *
      * @property startTimeMs the time that the phone call started, based on the notification's
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index 1faa9f3..84b0a1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -42,6 +42,7 @@
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.phone.StatusIconContainer
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.phone.ui.DarkIconManager
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarViewBinder
@@ -151,12 +152,11 @@
                         )
                     iconController.addIconGroup(darkIconManager)
 
-                    // TODO(b/372657935): This won't be needed once OngoingCallController is
-                    // implemented in recommended architecture
-                    ongoingCallController.setChipView(
-                        phoneStatusBarView.requireViewById(R.id.ongoing_activity_chip_primary)
-                    )
-
+                    if (!StatusBarChipsModernization.isEnabled) {
+                        ongoingCallController.setChipView(
+                            phoneStatusBarView.requireViewById(R.id.ongoing_activity_chip_primary)
+                        )
+                    }
                     // For notifications, first inflate the [NotificationIconContainer]
                     val notificationIconArea =
                         phoneStatusBarView.requireViewById<ViewGroup>(R.id.notification_icon_area)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index d1e4f64..3e24fbe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -68,6 +68,7 @@
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarComponent;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
+import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization;
 import com.android.systemui.statusbar.phone.ui.DarkIconManager;
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeHomeStatusBarViewBinder;
@@ -155,9 +156,9 @@
                 any(StatusBarWindowStateListener.class));
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testDisableNone() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testDisableNone() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
@@ -166,9 +167,9 @@
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testDisableSystemInfo_systemAnimationIdle_doesHide() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testDisableSystemInfo_systemAnimationIdle_doesHide() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
@@ -184,9 +185,9 @@
         assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testSystemStatusAnimation_startedDisabled_finishedWithAnimator_showsSystemInfo() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testSystemStatusAnimation_startedDisabled_finishedWithAnimator_showsSystemInfo() {
         // GIVEN the status bar hides the system info via disable flags, while there is no event
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
@@ -214,9 +215,9 @@
         assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testSystemStatusAnimation_systemInfoDisabled_staysInvisible() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testSystemStatusAnimation_systemInfoDisabled_staysInvisible() {
         // GIVEN the status bar hides the system info via disable flags, while there is no event
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_SYSTEM_INFO, 0, false);
@@ -231,9 +232,9 @@
         assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testSystemStatusAnimation_notDisabled_animatesAlphaZero() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testSystemStatusAnimation_notDisabled_animatesAlphaZero() {
         // GIVEN the status bar is not disabled
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
@@ -247,9 +248,9 @@
         assertEquals(0, getEndSideContentView().getAlpha(), 0.01);
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testSystemStatusAnimation_notDisabled_animatesBackToAlphaOne() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testSystemStatusAnimation_notDisabled_animatesBackToAlphaOne() {
         // GIVEN the status bar is not disabled
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
@@ -271,9 +272,9 @@
         assertEquals(1, getEndSideContentView().getAlpha(), 0.01);
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testDisableNotifications() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testDisableNotifications() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NOTIFICATION_ICONS, 0, false);
@@ -307,9 +308,9 @@
         assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testDisableClock() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testDisableClock() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_CLOCK, 0, false);
@@ -343,10 +344,10 @@
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_shadeOpenAndShouldHide_everythingHidden() {
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_shadeOpenAndShouldHide_everythingHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN the shade is open and configured to hide the status bar icons
@@ -361,10 +362,10 @@
         assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_shadeOpenButNotShouldHide_everythingShown() {
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_shadeOpenButNotShouldHide_everythingShown() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN the shade is open but *not* configured to hide the status bar icons
@@ -379,11 +380,11 @@
         assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
     }
 
-    /** Regression test for b/279790651. */
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_shadeOpenAndShouldHide_thenShadeNotOpenAndDozingUpdate_everythingShown() {
+  /** Regression test for b/279790651. */
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_shadeOpenAndShouldHide_thenShadeNotOpenAndDozingUpdate_everythingShown() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN the shade is open and configured to hide the status bar icons
@@ -409,9 +410,9 @@
         assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_notTransitioningToOccluded_everythingShown() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_notTransitioningToOccluded_everythingShown() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         mCollapsedStatusBarViewModel.isTransitioningFromLockscreenToOccluded().setValue(false);
@@ -424,10 +425,10 @@
         assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_isTransitioningToOccluded_everythingHidden() {
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_isTransitioningToOccluded_everythingHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         mCollapsedStatusBarViewModel.isTransitioningFromLockscreenToOccluded().setValue(true);
@@ -440,10 +441,10 @@
         assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_wasTransitioningToOccluded_transitionFinished_everythingShown() {
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_wasTransitioningToOccluded_transitionFinished_everythingShown() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN the transition is occurring
@@ -472,9 +473,13 @@
         assertEquals(View.GONE, getUserChipView().getVisibility());
     }
 
-    @Test
-    @DisableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarRootModernization.FLAG_NAME})
-    public void disable_noOngoingCall_chipHidden() {
+  @Test
+  @DisableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void disable_noOngoingCall_chipHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         when(mOngoingCallController.hasOngoingCall()).thenReturn(false);
@@ -484,9 +489,13 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @DisableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarRootModernization.FLAG_NAME})
-    public void disable_hasOngoingCall_chipDisplayedAndNotificationIconsHidden() {
+  @Test
+  @DisableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void disable_hasOngoingCall_chipDisplayedAndNotificationIconsHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
@@ -497,9 +506,13 @@
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @DisableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarRootModernization.FLAG_NAME})
-    public void disable_hasOngoingCallButNotificationIconsDisabled_chipHidden() {
+  @Test
+  @DisableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void disable_hasOngoingCallButNotificationIconsDisabled_chipHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
@@ -510,9 +523,13 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @DisableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarRootModernization.FLAG_NAME})
-    public void disable_hasOngoingCallButAlsoHun_chipHidden() {
+  @Test
+  @DisableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void disable_hasOngoingCallButAlsoHun_chipHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
@@ -523,9 +540,13 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @DisableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarRootModernization.FLAG_NAME})
-    public void disable_ongoingCallEnded_chipHidden() {
+  @Test
+  @DisableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void disable_ongoingCallEnded_chipHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // Ongoing call started
@@ -547,9 +568,13 @@
         assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @DisableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarRootModernization.FLAG_NAME})
-    public void disable_hasOngoingCall_hidesNotifsWithoutAnimation() {
+  @Test
+  @DisableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void disable_hasOngoingCall_hidesNotifsWithoutAnimation() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         // Enable animations for testing so that we can verify we still aren't animating
         fragment.enableAnimationsForTesting();
@@ -564,9 +589,13 @@
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @DisableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarRootModernization.FLAG_NAME})
-    public void screenSharingChipsDisabled_ignoresNewCallback() {
+  @Test
+  @DisableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void screenSharingChipsDisabled_ignoresNewCallback() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN there *is* an ongoing call via old callback
@@ -597,10 +626,10 @@
         assertEquals(View.GONE, getSecondaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void noOngoingActivity_chipHidden() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void noOngoingActivity_chipHidden() {
         resumeAndGetFragment();
 
         // TODO(b/332662551): We *should* be able to just set a value on
@@ -615,10 +644,10 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void hasPrimaryOngoingActivity_primaryChipDisplayedAndNotificationIconsHidden() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void hasPrimaryOngoingActivity_primaryChipDisplayedAndNotificationIconsHidden() {
         resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
@@ -630,12 +659,14 @@
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({
-            FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
-            StatusBarNotifChips.FLAG_NAME,
-            StatusBarRootModernization.FLAG_NAME})
-    public void hasPrimaryOngoingActivity_viewsUnchangedWhenRootModernizationFlagOn() {
+  @Test
+  @EnableFlags({
+    FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS,
+    StatusBarNotifChips.FLAG_NAME,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void hasPrimaryOngoingActivity_viewsUnchangedWhenRootModernizationFlagOn() {
         resumeAndGetFragment();
 
         assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
@@ -658,10 +689,14 @@
         assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags({StatusBarNotifChips.FLAG_NAME, StatusBarRootModernization.FLAG_NAME})
-    public void hasSecondaryOngoingActivity_butNotifsFlagOff_secondaryChipHidden() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({
+    StatusBarNotifChips.FLAG_NAME,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void hasSecondaryOngoingActivity_butNotifsFlagOff_secondaryChipHidden() {
         resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
@@ -672,10 +707,10 @@
         assertEquals(View.GONE, getSecondaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void hasSecondaryOngoingActivity_flagOn_secondaryChipShownAndNotificationIconsHidden() {
+  @Test
+  @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void hasSecondaryOngoingActivity_flagOn_secondaryChipShownAndNotificationIconsHidden() {
         resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
@@ -687,10 +722,14 @@
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags({StatusBarNotifChips.FLAG_NAME, StatusBarRootModernization.FLAG_NAME})
-    public void hasOngoingActivityButNotificationIconsDisabled_chipHidden_notifsFlagOff() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({
+    StatusBarNotifChips.FLAG_NAME,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void hasOngoingActivityButNotificationIconsDisabled_chipHidden_notifsFlagOff() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
@@ -704,10 +743,10 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void hasOngoingActivitiesButNotificationIconsDisabled_chipsHidden_notifsFlagOn() {
+  @Test
+  @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void hasOngoingActivitiesButNotificationIconsDisabled_chipsHidden_notifsFlagOn() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
@@ -722,10 +761,14 @@
         assertEquals(View.GONE, getSecondaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags({StatusBarNotifChips.FLAG_NAME, StatusBarRootModernization.FLAG_NAME})
-    public void hasOngoingActivityButAlsoHun_chipHidden_notifsFlagOff() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({
+    StatusBarNotifChips.FLAG_NAME,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void hasOngoingActivityButAlsoHun_chipHidden_notifsFlagOff() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
@@ -739,10 +782,10 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void hasOngoingActivitiesButAlsoHun_chipsHidden_notifsFlagOn() {
+  @Test
+  @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void hasOngoingActivitiesButAlsoHun_chipsHidden_notifsFlagOn() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged(
@@ -757,10 +800,14 @@
         assertEquals(View.GONE, getSecondaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags({StatusBarNotifChips.FLAG_NAME, StatusBarRootModernization.FLAG_NAME})
-    public void primaryOngoingActivityEnded_chipHidden_notifsFlagOff() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({
+    StatusBarNotifChips.FLAG_NAME,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void primaryOngoingActivityEnded_chipHidden_notifsFlagOff() {
         resumeAndGetFragment();
 
         // Ongoing activity started
@@ -780,10 +827,10 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void primaryOngoingActivityEnded_chipHidden_notifsFlagOn() {
+  @Test
+  @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void primaryOngoingActivityEnded_chipHidden_notifsFlagOn() {
         resumeAndGetFragment();
 
         // Ongoing activity started
@@ -803,10 +850,10 @@
         assertEquals(View.GONE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void secondaryOngoingActivityEnded_chipHidden() {
+  @Test
+  @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void secondaryOngoingActivityEnded_chipHidden() {
         resumeAndGetFragment();
 
         // Secondary ongoing activity started
@@ -826,10 +873,14 @@
         assertEquals(View.GONE, getSecondaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags({StatusBarNotifChips.FLAG_NAME, StatusBarRootModernization.FLAG_NAME})
-    public void hasOngoingActivity_hidesNotifsWithoutAnimation_notifsFlagOff() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({
+    StatusBarNotifChips.FLAG_NAME,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void hasOngoingActivity_hidesNotifsWithoutAnimation_notifsFlagOff() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         // Enable animations for testing so that we can verify we still aren't animating
         fragment.enableAnimationsForTesting();
@@ -845,10 +896,10 @@
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void hasOngoingActivity_hidesNotifsWithoutAnimation_notifsFlagOn() {
+  @Test
+  @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void hasOngoingActivity_hidesNotifsWithoutAnimation_notifsFlagOn() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         // Enable animations for testing so that we can verify we still aren't animating
         fragment.enableAnimationsForTesting();
@@ -864,10 +915,14 @@
         assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
     }
 
-    @Test
-    @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
-    @DisableFlags({StatusBarNotifChips.FLAG_NAME, StatusBarRootModernization.FLAG_NAME})
-    public void screenSharingChipsEnabled_ignoresOngoingCallController_notifsFlagOff() {
+  @Test
+  @EnableFlags(FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+  @DisableFlags({
+    StatusBarNotifChips.FLAG_NAME,
+    StatusBarRootModernization.FLAG_NAME,
+    StatusBarChipsModernization.FLAG_NAME
+  })
+  public void screenSharingChipsEnabled_ignoresOngoingCallController_notifsFlagOff() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN there *is* an ongoing call via old callback
@@ -897,10 +952,10 @@
         assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void screenSharingChipsEnabled_ignoresOngoingCallController_notifsFlagOn() {
+  @Test
+  @EnableFlags({FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS, StatusBarNotifChips.FLAG_NAME})
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void screenSharingChipsEnabled_ignoresOngoingCallController_notifsFlagOn() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN there *is* an ongoing call via old callback
@@ -931,10 +986,10 @@
         assertEquals(View.VISIBLE, getSecondaryOngoingActivityChipView().getVisibility());
     }
 
-    @Test
-    @EnableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void isHomeStatusBarAllowedByScene_false_everythingHidden() {
+  @Test
+  @EnableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void isHomeStatusBarAllowedByScene_false_everythingHidden() {
         resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);
@@ -945,10 +1000,10 @@
         assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @EnableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void isHomeStatusBarAllowedByScene_true_everythingShown() {
+  @Test
+  @EnableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void isHomeStatusBarAllowedByScene_true_everythingShown() {
         resumeAndGetFragment();
 
         mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(true);
@@ -959,10 +1014,10 @@
         assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @EnableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_isHomeStatusBarAllowedBySceneFalse_disableValuesIgnored() {
+  @Test
+  @EnableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_isHomeStatusBarAllowedBySceneFalse_disableValuesIgnored() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN the scene doesn't allow the status bar
@@ -977,10 +1032,10 @@
         assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @EnableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_isHomeStatusBarAllowedBySceneTrue_disableValuesUsed() {
+  @Test
+  @EnableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_isHomeStatusBarAllowedBySceneTrue_disableValuesUsed() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN the scene does allow the status bar
@@ -995,10 +1050,10 @@
         assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void isHomeStatusBarAllowedByScene_sceneContainerDisabled_valueNotUsed() {
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void isHomeStatusBarAllowedByScene_sceneContainerDisabled_valueNotUsed() {
         resumeAndGetFragment();
 
         // Even if the scene says to hide the home status bar
@@ -1010,9 +1065,9 @@
         assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_isDozing_clockAndSystemInfoVisible() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_isDozing_clockAndSystemInfoVisible() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         when(mStatusBarStateController.isDozing()).thenReturn(true);
 
@@ -1022,9 +1077,9 @@
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_NotDozing_clockAndSystemInfoVisible() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_NotDozing_clockAndSystemInfoVisible() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         when(mStatusBarStateController.isDozing()).thenReturn(false);
 
@@ -1034,9 +1089,9 @@
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_headsUpShouldBeVisibleTrue_clockDisabled() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_headsUpShouldBeVisibleTrue_clockDisabled() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(true);
 
@@ -1045,9 +1100,9 @@
         assertEquals(View.GONE, getClockView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void disable_headsUpShouldBeVisibleFalse_clockNotDisabled() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void disable_headsUpShouldBeVisibleFalse_clockNotDisabled() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(false);
 
@@ -1098,10 +1153,10 @@
         assertFalse(contains);
     }
 
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testStatusBarIcons_hiddenThroughoutCameraLaunch() {
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testStatusBarIcons_hiddenThroughoutCameraLaunch() {
         final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         mockSecureCameraLaunch(fragment, true /* launched */);
@@ -1121,10 +1176,10 @@
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
-    @Test
-    @DisableSceneContainer
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testStatusBarIcons_hiddenThroughoutLockscreenToDreamTransition() {
+  @Test
+  @DisableSceneContainer
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testStatusBarIcons_hiddenThroughoutLockscreenToDreamTransition() {
         final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN a transition to dream has started
@@ -1158,9 +1213,9 @@
         assertEquals(View.VISIBLE, getClockView().getVisibility());
     }
 
-    @Test
-    @DisableFlags(StatusBarRootModernization.FLAG_NAME)
-    public void testStatusBarIcons_lockscreenToDreamTransitionButNotDreaming_iconsVisible() {
+  @Test
+  @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME})
+  public void testStatusBarIcons_lockscreenToDreamTransitionButNotDreaming_iconsVisible() {
         final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
         // WHEN a transition to dream has started but we're *not* dreaming
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
index fcd14d8..d8d4d2b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
@@ -20,12 +20,14 @@
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.statusbar.chips.statusBarChipsLogger
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
+import com.android.systemui.statusbar.phone.ongoingcall.domain.interactor.ongoingCallInteractor
 
 val Kosmos.callChipInteractor: CallChipInteractor by
     Kosmos.Fixture {
         CallChipInteractor(
             scope = applicationCoroutineScope,
             repository = ongoingCallRepository,
+            ongoingCallInteractor = ongoingCallInteractor,
             logger = statusBarChipsLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorKosmos.kt
new file mode 100644
index 0000000..51fb36f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.phone.ongoingcall.domain.interactor
+
+import com.android.systemui.activity.data.repository.activityManagerRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+
+val Kosmos.ongoingCallInteractor: OngoingCallInteractor by
+    Kosmos.Fixture {
+      OngoingCallInteractor(
+          scope = applicationCoroutineScope,
+          activeNotificationsInteractor = activeNotificationsInteractor,
+          activityManagerRepository = activityManagerRepository,
+          logBuffer = logcatLogBuffer("OngoingCallInteractorKosmos"),
+      )
+    }