[Chipbar] Rename MediaTttChipControllerSender to ChipbarCoordinator,
since it has all the chipbar logic.

Future CLs will remove the media-specific logic from ChipbarCoordinator.

Bug: 245610654
Test: manual: Verify chipbar commands still work
Test: media.taptotransfer tests
Test: temporarydisplay tests
Change-Id: I0af8480c9ee400496237f144aaba907ab5a99e30
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
index 491ec20..a850238 100644
--- a/packages/SystemUI/ktfmt_includes.txt
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -246,8 +246,6 @@
 -packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLogger.kt
 -packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
 -packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
 -packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
 -packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
 -packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
@@ -528,6 +526,8 @@
 -packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
 -packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewInfo.kt
 -packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+-packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarRootView.kt
 -packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
 -packages/SystemUI/src/com/android/systemui/toast/ToastLogger.kt
 -packages/SystemUI/src/com/android/systemui/tv/TVSystemUICoreStartableModule.kt
@@ -678,7 +678,6 @@
 -packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitorTest.kt
@@ -833,6 +832,7 @@
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
 -packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
diff --git a/packages/SystemUI/res/layout/media_ttt_chip.xml b/packages/SystemUI/res/layout/chipbar.xml
similarity index 96%
rename from packages/SystemUI/res/layout/media_ttt_chip.xml
rename to packages/SystemUI/res/layout/chipbar.xml
index ae8e38e..4da7711 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip.xml
+++ b/packages/SystemUI/res/layout/chipbar.xml
@@ -16,7 +16,7 @@
 <!-- Wrap in a frame layout so that we can update the margins on the inner layout. (Since this view
      is the root view of a window, we cannot change the root view's margins.) -->
 <!-- Alphas start as 0 because the view will be animated in. -->
-<com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView
+<com.android.systemui.temporarydisplay.chipbar.ChipbarRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/media_ttt_sender_chip"
@@ -97,4 +97,4 @@
             />
 
     </LinearLayout>
-</com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView>
+</com.android.systemui.temporarydisplay.chipbar.ChipbarRootView>
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 55eda0a..303c7cd 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -34,13 +34,13 @@
 import com.android.systemui.media.RingtonePlayer
 import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper
 import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver
-import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender
 import com.android.systemui.power.PowerUI
 import com.android.systemui.recents.Recents
 import com.android.systemui.settings.dagger.MultiUserUtilsModule
 import com.android.systemui.shortcut.ShortcutKeyDispatcher
 import com.android.systemui.statusbar.notification.InstantAppNotifier
 import com.android.systemui.statusbar.phone.KeyguardLiftController
+import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
 import com.android.systemui.theme.ThemeOverlayController
 import com.android.systemui.toast.ToastUI
 import com.android.systemui.usb.StorageNotification
@@ -225,17 +225,15 @@
             sysui: MediaTttChipControllerReceiver
     ): CoreStartable
 
-    /** Inject into MediaTttChipControllerSender. */
-    @Binds
-    @IntoMap
-    @ClassKey(MediaTttChipControllerSender::class)
-    abstract fun bindMediaTttChipControllerSender(
-            sysui: MediaTttChipControllerSender
-    ): CoreStartable
-
     /** Inject into MediaTttCommandLineHelper. */
     @Binds
     @IntoMap
     @ClassKey(MediaTttCommandLineHelper::class)
     abstract fun bindMediaTttCommandLineHelper(sysui: MediaTttCommandLineHelper): CoreStartable
+
+    /** Inject into ChipbarCoordinator. */
+    @Binds
+    @IntoMap
+    @ClassKey(ChipbarCoordinator::class)
+    abstract fun bindChipbarController(sysui: ChipbarCoordinator): CoreStartable
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
index 66c036c..a8a8433 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
@@ -31,9 +31,7 @@
 import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
 import com.android.systemui.media.taptotransfer.MediaTttFlags;
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger;
-import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver;
 import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger;
-import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender;
 import com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger;
 
 import java.util.Optional;
@@ -94,30 +92,6 @@
         return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager);
     }
 
-    /** */
-    @Provides
-    @SysUISingleton
-    static Optional<MediaTttChipControllerSender> providesMediaTttChipControllerSender(
-            MediaTttFlags mediaTttFlags,
-            Lazy<MediaTttChipControllerSender> controllerSenderLazy) {
-        if (!mediaTttFlags.isMediaTttEnabled()) {
-            return Optional.empty();
-        }
-        return Optional.of(controllerSenderLazy.get());
-    }
-
-    /** */
-    @Provides
-    @SysUISingleton
-    static Optional<MediaTttChipControllerReceiver> providesMediaTttChipControllerReceiver(
-            MediaTttFlags mediaTttFlags,
-            Lazy<MediaTttChipControllerReceiver> controllerReceiverLazy) {
-        if (!mediaTttFlags.isMediaTttEnabled()) {
-            return Optional.empty();
-        }
-        return Optional.of(controllerReceiverLazy.get());
-    }
-
     @Provides
     @SysUISingleton
     @MediaTttSenderLogger
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
index 6379960..b5a0483 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/README.md
@@ -41,3 +41,5 @@
 ## Testing
 If you want to test out the tap-to-transfer chip without using the `@SystemApi`s, you can use adb
 commands instead. Refer to `MediaTttCommandLineHelper` for information about adb commands.
+
+TODO(b/245610654): Update this page once the chipbar migration is complete.
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 1461293..0163031 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.MediaTttFlags
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.media.taptotransfer.common.MediaTttUtils
 import com.android.systemui.statusbar.CommandQueue
@@ -64,6 +65,7 @@
         configurationController: ConfigurationController,
         powerManager: PowerManager,
         @Main private val mainHandler: Handler,
+        private val mediaTttFlags: MediaTttFlags,
         private val uiEventLogger: MediaTttReceiverUiEventLogger,
         private val viewUtil: ViewUtil,
 ) : TemporaryViewDisplayController<ChipReceiverInfo, MediaTttLogger>(
@@ -138,7 +140,9 @@
     }
 
     override fun start() {
-        commandQueue.addCallback(commandQueueCallbacks)
+        if (mediaTttFlags.isMediaTttEnabled()) {
+            commandQueue.addCallback(commandQueueCallbacks)
+        }
     }
 
     override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
index aae973d..c24b030 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.R
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.temporarydisplay.DEFAULT_TIMEOUT_MILLIS
+import com.android.systemui.temporarydisplay.chipbar.ChipSenderInfo
+import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
 
 /**
  * A class enumerating all the possible states of the media tap-to-transfer chip on the sender
@@ -105,7 +107,7 @@
         transferStatus = TransferStatus.SUCCEEDED,
     ) {
         override fun undoClickListener(
-            controllerSender: MediaTttChipControllerSender,
+            chipbarCoordinator: ChipbarCoordinator,
             routeInfo: MediaRoute2Info,
             undoCallback: IUndoMediaTransferCallback?,
             uiEventLogger: MediaTttSenderUiEventLogger,
@@ -123,9 +125,9 @@
                 undoCallback.onUndoTriggered()
                 // The external service should eventually send us a TransferToThisDeviceTriggered
                 // state, but that may take too long to go through the binder and the user may be
-                // confused ast o why the UI hasn't changed yet. So, we immediately change the UI
+                // confused as to why the UI hasn't changed yet. So, we immediately change the UI
                 // here.
-                controllerSender.displayView(
+                chipbarCoordinator.displayView(
                     ChipSenderInfo(
                         TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, undoCallback
                     )
@@ -144,7 +146,7 @@
         transferStatus = TransferStatus.SUCCEEDED,
     ) {
         override fun undoClickListener(
-            controllerSender: MediaTttChipControllerSender,
+            chipbarCoordinator: ChipbarCoordinator,
             routeInfo: MediaRoute2Info,
             undoCallback: IUndoMediaTransferCallback?,
             uiEventLogger: MediaTttSenderUiEventLogger,
@@ -164,7 +166,7 @@
                 // state, but that may take too long to go through the binder and the user may be
                 // confused as to why the UI hasn't changed yet. So, we immediately change the UI
                 // here.
-                controllerSender.displayView(
+                chipbarCoordinator.displayView(
                     ChipSenderInfo(
                         TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, undoCallback
                     )
@@ -213,13 +215,13 @@
      * Returns a click listener for the undo button on the chip. Returns null if this chip state
      * doesn't have an undo button.
      *
-     * @param controllerSender passed as a parameter in case we want to display a new chip state
+     * @param chipbarCoordinator passed as a parameter in case we want to display a new chipbar
      *   when undo is clicked.
      * @param undoCallback if present, the callback that should be called when the user clicks the
      *   undo button. The undo button will only be shown if this is non-null.
      */
     open fun undoClickListener(
-        controllerSender: MediaTttChipControllerSender,
+        chipbarCoordinator: ChipbarCoordinator,
         routeInfo: MediaRoute2Info,
         undoCallback: IUndoMediaTransferCallback?,
         uiEventLogger: MediaTttSenderUiEventLogger,
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
similarity index 83%
rename from packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
rename to packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index ca066f4..2bce348 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.media.taptotransfer.sender
+package com.android.systemui.temporarydisplay.chipbar
 
 import android.app.StatusBarManager
 import android.content.Context
@@ -38,8 +38,13 @@
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.media.taptotransfer.MediaTttFlags
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.media.taptotransfer.common.MediaTttUtils
+import com.android.systemui.media.taptotransfer.sender.ChipStateSender
+import com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger
+import com.android.systemui.media.taptotransfer.sender.MediaTttSenderUiEventLogger
+import com.android.systemui.media.taptotransfer.sender.TransferStatus
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -51,11 +56,26 @@
 import javax.inject.Inject
 
 /**
- * A controller to display and hide the Media Tap-To-Transfer chip on the **sending** device. This
- * chip is shown when a user is transferring media to/from this device and a receiver device.
+ * A coordinator for showing/hiding the chipbar.
+ *
+ * The chipbar is a UI element that displays on top of all content. It appears at the top of the
+ * screen and consists of an icon, one line of text, and an optional end icon or action. It will
+ * auto-dismiss after some amount of seconds. The user is *not* able to manually dismiss the
+ * chipbar.
+ *
+ * It should be only be used for critical and temporary information that the user *must* be aware
+ * of. In general, prefer using heads-up notifications, since they are dismissable and will remain
+ * in the list of notifications until the user dismisses them.
+ *
+ * Only one chipbar may be shown at a time.
+ * TODO(b/245610654): Should we just display whichever chipbar was most recently requested, or do we
+ *   need to maintain a priority ordering?
+ *
+ * TODO(b/245610654): Remove all media-related items from this class so it's just for generic
+ *   chipbars.
  */
 @SysUISingleton
-open class MediaTttChipControllerSender @Inject constructor(
+open class ChipbarCoordinator @Inject constructor(
         private val commandQueue: CommandQueue,
         context: Context,
         @MediaTttSenderLogger logger: MediaTttLogger,
@@ -67,6 +87,7 @@
         private val uiEventLogger: MediaTttSenderUiEventLogger,
         private val falsingManager: FalsingManager,
         private val falsingCollector: FalsingCollector,
+        private val mediaTttFlags: MediaTttFlags,
         private val viewUtil: ViewUtil,
 ) : TemporaryViewDisplayController<ChipSenderInfo, MediaTttLogger>(
         context,
@@ -76,12 +97,12 @@
         accessibilityManager,
         configurationController,
         powerManager,
-        R.layout.media_ttt_chip,
+        R.layout.chipbar,
         MediaTttUtils.WINDOW_TITLE,
         MediaTttUtils.WAKE_REASON,
 ) {
 
-    private lateinit var parent: MediaTttChipRootView
+    private lateinit var parent: ChipbarRootView
 
     override val windowLayoutParams = commonWindowLayoutParams.apply {
         gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
@@ -93,7 +114,7 @@
                 routeInfo: MediaRoute2Info,
                 undoCallback: IUndoMediaTransferCallback?
         ) {
-            this@MediaTttChipControllerSender.updateMediaTapToTransferSenderDisplay(
+            this@ChipbarCoordinator.updateMediaTapToTransferSenderDisplay(
                 displayState, routeInfo, undoCallback
             )
         }
@@ -122,7 +143,9 @@
     }
 
     override fun start() {
-        commandQueue.addCallback(commandQueueCallbacks)
+        if (mediaTttFlags.isMediaTttEnabled()) {
+            commandQueue.addCallback(commandQueueCallbacks)
+        }
     }
 
     override fun updateView(
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarRootView.kt
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
rename to packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarRootView.kt
index 3373159..edec420 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarRootView.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.media.taptotransfer.sender
+package com.android.systemui.temporarydisplay.chipbar
 
 import android.content.Context
 import android.util.AttributeSet
@@ -22,8 +22,8 @@
 import android.widget.FrameLayout
 import com.android.systemui.Gefingerpoken
 
-/** A simple subclass that allows for observing touch events on chip. */
-class MediaTttChipRootView(
+/** A simple subclass that allows for observing touch events on chipbar. */
+class ChipbarRootView(
         context: Context,
         attrs: AttributeSet?
 ) : FrameLayout(context, attrs) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 9577274..8c3ae3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -34,6 +34,7 @@
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.media.taptotransfer.MediaTttFlags
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -49,6 +50,7 @@
 import org.mockito.ArgumentCaptor
 import org.mockito.Mock
 import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -70,6 +72,8 @@
     @Mock
     private lateinit var configurationController: ConfigurationController
     @Mock
+    private lateinit var mediaTttFlags: MediaTttFlags
+    @Mock
     private lateinit var powerManager: PowerManager
     @Mock
     private lateinit var viewUtil: ViewUtil
@@ -85,6 +89,7 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(true)
 
         fakeAppIconDrawable = context.getDrawable(R.drawable.ic_cake)!!
         whenever(packageManager.getApplicationIcon(PACKAGE_NAME)).thenReturn(fakeAppIconDrawable)
@@ -107,6 +112,7 @@
             configurationController,
             powerManager,
             Handler.getMain(),
+            mediaTttFlags,
             receiverUiEventLogger,
             viewUtil,
         )
@@ -118,6 +124,30 @@
     }
 
     @Test
+    fun commandQueueCallback_flagOff_noCallbackAdded() {
+        reset(commandQueue)
+        whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(false)
+
+        controllerReceiver = MediaTttChipControllerReceiver(
+            commandQueue,
+            context,
+            logger,
+            windowManager,
+            FakeExecutor(FakeSystemClock()),
+            accessibilityManager,
+            configurationController,
+            powerManager,
+            Handler.getMain(),
+            mediaTttFlags,
+            receiverUiEventLogger,
+            viewUtil,
+        )
+        controllerReceiver.start()
+
+        verify(commandQueue, never()).addCallback(any())
+    }
+
+    @Test
     fun commandQueueCallback_closeToSender_triggersChip() {
         val appName = "FakeAppName"
         commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index c4abedd..b10aa12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -253,7 +253,7 @@
         accessibilityManager,
         configurationController,
         powerManager,
-        R.layout.media_ttt_chip,
+        R.layout.chipbar,
         "Window Title",
         "WAKE_REASON",
     ) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
similarity index 87%
rename from packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index 3a8a51d..f3b8837 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.media.taptotransfer.sender
+package com.android.systemui.temporarydisplay.chipbar
 
 import android.app.StatusBarManager
 import android.content.Context
@@ -37,8 +37,12 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.media.taptotransfer.MediaTttFlags
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger
+import com.android.systemui.media.taptotransfer.sender.ChipStateSender
+import com.android.systemui.media.taptotransfer.sender.MediaTttSenderUiEventLogger
+import com.android.systemui.media.taptotransfer.sender.MediaTttSenderUiEvents
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -56,6 +60,7 @@
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -63,8 +68,8 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper
-class MediaTttChipControllerSenderTest : SysuiTestCase() {
-    private lateinit var controllerSender: TestMediaTttChipControllerSender
+class ChipbarCoordinatorTest : SysuiTestCase() {
+    private lateinit var underTest: TestChipbarCoordinator
 
     @Mock
     private lateinit var packageManager: PackageManager
@@ -77,6 +82,8 @@
     @Mock
     private lateinit var configurationController: ConfigurationController
     @Mock
+    private lateinit var mediaTttFlags: MediaTttFlags
+    @Mock
     private lateinit var powerManager: PowerManager
     @Mock
     private lateinit var windowManager: WindowManager
@@ -98,6 +105,7 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(true)
 
         fakeAppIconDrawable = context.getDrawable(R.drawable.ic_cake)!!
         whenever(applicationInfo.loadLabel(packageManager)).thenReturn(APP_NAME)
@@ -115,7 +123,7 @@
 
         whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any())).thenReturn(TIMEOUT)
 
-        controllerSender = TestMediaTttChipControllerSender(
+        underTest = TestChipbarCoordinator(
             commandQueue,
             context,
             logger,
@@ -127,9 +135,10 @@
             senderUiEventLogger,
             falsingManager,
             falsingCollector,
+            mediaTttFlags,
             viewUtil,
         )
-        controllerSender.start()
+        underTest.start()
 
         val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
         verify(commandQueue).addCallback(callbackCaptor.capture())
@@ -137,6 +146,30 @@
     }
 
     @Test
+    fun commandQueueCallback_flagOff_noCallbackAdded() {
+        reset(commandQueue)
+        whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(false)
+        underTest = TestChipbarCoordinator(
+            commandQueue,
+            context,
+            logger,
+            windowManager,
+            fakeExecutor,
+            accessibilityManager,
+            configurationController,
+            powerManager,
+            senderUiEventLogger,
+            falsingManager,
+            falsingCollector,
+            mediaTttFlags,
+            viewUtil,
+        )
+        underTest.start()
+
+        verify(commandQueue, never()).addCallback(any())
+    }
+
+    @Test
     fun commandQueueCallback_almostCloseToStartCast_triggersCorrectChip() {
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(
             StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
@@ -322,7 +355,7 @@
     @Test
     fun almostCloseToStartCast_appIcon_deviceName_noLoadingIcon_noUndo_noFailureIcon() {
         val state = almostCloseToStartCast()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -338,7 +371,7 @@
     @Test
     fun almostCloseToEndCast_appIcon_deviceName_noLoadingIcon_noUndo_noFailureIcon() {
         val state = almostCloseToEndCast()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -354,7 +387,7 @@
     @Test
     fun transferToReceiverTriggered_appIcon_loadingIcon_noUndo_noFailureIcon() {
         val state = transferToReceiverTriggered()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -370,7 +403,7 @@
     @Test
     fun transferToThisDeviceTriggered_appIcon_loadingIcon_noUndo_noFailureIcon() {
         val state = transferToThisDeviceTriggered()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -386,7 +419,7 @@
     @Test
     fun transferToReceiverSucceeded_appIcon_deviceName_noLoadingIcon_noFailureIcon() {
         val state = transferToReceiverSucceeded()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -400,7 +433,7 @@
 
     @Test
     fun transferToReceiverSucceeded_nullUndoRunnable_noUndo() {
-        controllerSender.displayView(transferToReceiverSucceeded(undoCallback = null))
+        underTest.displayView(transferToReceiverSucceeded(undoCallback = null))
 
         val chipView = getChipView()
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
@@ -411,7 +444,7 @@
         val undoCallback = object : IUndoMediaTransferCallback.Stub() {
             override fun onUndoTriggered() {}
         }
-        controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
+        underTest.displayView(transferToReceiverSucceeded(undoCallback))
 
         val chipView = getChipView()
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.VISIBLE)
@@ -427,7 +460,7 @@
             }
         }
 
-        controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
+        underTest.displayView(transferToReceiverSucceeded(undoCallback))
         getChipView().getUndoButton().performClick()
 
         assertThat(undoCallbackCalled).isTrue()
@@ -443,7 +476,7 @@
             }
         }
 
-        controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
+        underTest.displayView(transferToReceiverSucceeded(undoCallback))
         getChipView().getUndoButton().performClick()
 
         assertThat(undoCallbackCalled).isFalse()
@@ -459,7 +492,7 @@
             }
         }
 
-        controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
+        underTest.displayView(transferToReceiverSucceeded(undoCallback))
         getChipView().getUndoButton().performClick()
 
         assertThat(undoCallbackCalled).isTrue()
@@ -470,7 +503,7 @@
         val undoCallback = object : IUndoMediaTransferCallback.Stub() {
             override fun onUndoTriggered() {}
         }
-        controllerSender.displayView(transferToReceiverSucceeded(undoCallback))
+        underTest.displayView(transferToReceiverSucceeded(undoCallback))
 
         getChipView().getUndoButton().performClick()
 
@@ -485,7 +518,7 @@
     @Test
     fun transferToThisDeviceSucceeded_appIcon_deviceName_noLoadingIcon_noFailureIcon() {
         val state = transferToThisDeviceSucceeded()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -499,7 +532,7 @@
 
     @Test
     fun transferToThisDeviceSucceeded_nullUndoRunnable_noUndo() {
-        controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback = null))
+        underTest.displayView(transferToThisDeviceSucceeded(undoCallback = null))
 
         val chipView = getChipView()
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
@@ -510,7 +543,7 @@
         val undoCallback = object : IUndoMediaTransferCallback.Stub() {
             override fun onUndoTriggered() {}
         }
-        controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback))
+        underTest.displayView(transferToThisDeviceSucceeded(undoCallback))
 
         val chipView = getChipView()
         assertThat(chipView.getUndoButton().visibility).isEqualTo(View.VISIBLE)
@@ -526,7 +559,7 @@
             }
         }
 
-        controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback))
+        underTest.displayView(transferToThisDeviceSucceeded(undoCallback))
         getChipView().getUndoButton().performClick()
 
         assertThat(undoCallbackCalled).isTrue()
@@ -537,7 +570,7 @@
         val undoCallback = object : IUndoMediaTransferCallback.Stub() {
             override fun onUndoTriggered() {}
         }
-        controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback))
+        underTest.displayView(transferToThisDeviceSucceeded(undoCallback))
 
         getChipView().getUndoButton().performClick()
 
@@ -552,7 +585,7 @@
     @Test
     fun transferToReceiverFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
         val state = transferToReceiverFailed()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -568,7 +601,7 @@
     @Test
     fun transferToThisDeviceFailed_appIcon_noDeviceName_noLoadingIcon_noUndo_failureIcon() {
         val state = transferToThisDeviceFailed()
-        controllerSender.displayView(state)
+        underTest.displayView(state)
 
         val chipView = getChipView()
         assertThat(chipView.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
@@ -583,24 +616,24 @@
 
     @Test
     fun changeFromAlmostCloseToStartToTransferTriggered_loadingIconAppears() {
-        controllerSender.displayView(almostCloseToStartCast())
-        controllerSender.displayView(transferToReceiverTriggered())
+        underTest.displayView(almostCloseToStartCast())
+        underTest.displayView(transferToReceiverTriggered())
 
         assertThat(getChipView().getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
     }
 
     @Test
     fun changeFromTransferTriggeredToTransferSucceeded_loadingIconDisappears() {
-        controllerSender.displayView(transferToReceiverTriggered())
-        controllerSender.displayView(transferToReceiverSucceeded())
+        underTest.displayView(transferToReceiverTriggered())
+        underTest.displayView(transferToReceiverSucceeded())
 
         assertThat(getChipView().getLoadingIconVisibility()).isEqualTo(View.GONE)
     }
 
     @Test
     fun changeFromTransferTriggeredToTransferSucceeded_undoButtonAppears() {
-        controllerSender.displayView(transferToReceiverTriggered())
-        controllerSender.displayView(
+        underTest.displayView(transferToReceiverTriggered())
+        underTest.displayView(
             transferToReceiverSucceeded(
                 object : IUndoMediaTransferCallback.Stub() {
                     override fun onUndoTriggered() {}
@@ -613,26 +646,26 @@
 
     @Test
     fun changeFromTransferSucceededToAlmostCloseToStart_undoButtonDisappears() {
-        controllerSender.displayView(transferToReceiverSucceeded())
-        controllerSender.displayView(almostCloseToStartCast())
+        underTest.displayView(transferToReceiverSucceeded())
+        underTest.displayView(almostCloseToStartCast())
 
         assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.GONE)
     }
 
     @Test
     fun changeFromTransferTriggeredToTransferFailed_failureIconAppears() {
-        controllerSender.displayView(transferToReceiverTriggered())
-        controllerSender.displayView(transferToReceiverFailed())
+        underTest.displayView(transferToReceiverTriggered())
+        underTest.displayView(transferToReceiverFailed())
 
         assertThat(getChipView().getFailureIcon().visibility).isEqualTo(View.VISIBLE)
     }
 
     @Test
     fun transferToReceiverTriggeredThenRemoveView_viewStillDisplayed() {
-        controllerSender.displayView(transferToReceiverTriggered())
+        underTest.displayView(transferToReceiverTriggered())
         fakeClock.advanceTime(1000L)
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeExecutor.runAllReady()
 
         verify(windowManager, never()).removeView(any())
@@ -641,7 +674,7 @@
 
     @Test
     fun transferToReceiverTriggeredThenFarFromReceiver_viewStillDisplayed() {
-        controllerSender.displayView(transferToReceiverTriggered())
+        underTest.displayView(transferToReceiverTriggered())
 
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(
             StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
@@ -656,9 +689,9 @@
 
     @Test
     fun transferToReceiverTriggeredThenRemoveView_eventuallyTimesOut() {
-        controllerSender.displayView(transferToReceiverTriggered())
+        underTest.displayView(transferToReceiverTriggered())
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
@@ -666,10 +699,10 @@
 
     @Test
     fun transferToThisDeviceTriggeredThenRemoveView_viewStillDisplayed() {
-        controllerSender.displayView(transferToThisDeviceTriggered())
+        underTest.displayView(transferToThisDeviceTriggered())
         fakeClock.advanceTime(1000L)
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeExecutor.runAllReady()
 
         verify(windowManager, never()).removeView(any())
@@ -678,9 +711,9 @@
 
     @Test
     fun transferToThisDeviceTriggeredThenRemoveView_eventuallyTimesOut() {
-        controllerSender.displayView(transferToThisDeviceTriggered())
+        underTest.displayView(transferToThisDeviceTriggered())
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
@@ -688,7 +721,7 @@
 
     @Test
     fun transferToThisDeviceTriggeredThenFarFromReceiver_viewStillDisplayed() {
-        controllerSender.displayView(transferToThisDeviceTriggered())
+        underTest.displayView(transferToThisDeviceTriggered())
 
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(
             StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
@@ -703,9 +736,9 @@
 
     @Test
     fun transferToReceiverSucceededThenRemoveView_viewStillDisplayed() {
-        controllerSender.displayView(transferToReceiverSucceeded())
+        underTest.displayView(transferToReceiverSucceeded())
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeExecutor.runAllReady()
 
         verify(windowManager, never()).removeView(any())
@@ -714,9 +747,9 @@
 
     @Test
     fun transferToReceiverSucceededThenRemoveView_eventuallyTimesOut() {
-        controllerSender.displayView(transferToReceiverSucceeded())
+        underTest.displayView(transferToReceiverSucceeded())
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
@@ -724,7 +757,7 @@
 
     @Test
     fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayed() {
-        controllerSender.displayView(transferToReceiverSucceeded())
+        underTest.displayView(transferToReceiverSucceeded())
 
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(
             StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
@@ -739,9 +772,9 @@
 
     @Test
     fun transferToThisDeviceSucceededThenRemoveView_viewStillDisplayed() {
-        controllerSender.displayView(transferToThisDeviceSucceeded())
+        underTest.displayView(transferToThisDeviceSucceeded())
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeExecutor.runAllReady()
 
         verify(windowManager, never()).removeView(any())
@@ -750,9 +783,9 @@
 
     @Test
     fun transferToThisDeviceSucceededThenRemoveView_eventuallyTimesOut() {
-        controllerSender.displayView(transferToThisDeviceSucceeded())
+        underTest.displayView(transferToThisDeviceSucceeded())
 
-        controllerSender.removeView("fakeRemovalReason")
+        underTest.removeView("fakeRemovalReason")
         fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
@@ -760,7 +793,7 @@
 
     @Test
     fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayed() {
-        controllerSender.displayView(transferToThisDeviceSucceeded())
+        underTest.displayView(transferToThisDeviceSucceeded())
 
         commandQueueCallback.updateMediaTapToTransferSenderDisplay(
             StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
@@ -823,7 +856,7 @@
     private fun transferToThisDeviceFailed() =
         ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo)
 
-    private class TestMediaTttChipControllerSender(
+    private class TestChipbarCoordinator(
         commandQueue: CommandQueue,
         context: Context,
         @MediaTttReceiverLogger logger: MediaTttLogger,
@@ -835,8 +868,9 @@
         uiEventLogger: MediaTttSenderUiEventLogger,
         falsingManager: FalsingManager,
         falsingCollector: FalsingCollector,
+        mediaTttFlags: MediaTttFlags,
         viewUtil: ViewUtil,
-    ) : MediaTttChipControllerSender(
+    ) : ChipbarCoordinator(
         commandQueue,
         context,
         logger,
@@ -848,6 +882,7 @@
         uiEventLogger,
         falsingManager,
         falsingCollector,
+        mediaTttFlags,
         viewUtil,
     ) {
         override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) {