diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt index 491ec20c519da..a850238eb52fa 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 ae8e38e2634b0..4da77118f00bf 100644 --- a/packages/SystemUI/res/layout/media_ttt_chip.xml +++ b/packages/SystemUI/res/layout/chipbar.xml @@ -16,7 +16,7 @@ - - + diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index 55eda0a0cb8a1..721c0ba4f8654 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -34,13 +34,14 @@ import com.android.systemui.log.SessionTracker 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.media.taptotransfer.sender.MediaTttSenderCoordinator 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 @@ -217,6 +218,12 @@ abstract class SystemUICoreStartableModule { @ClassKey(KeyguardLiftController::class) abstract fun bindKeyguardLiftController(sysui: KeyguardLiftController): CoreStartable + /** Inject into MediaTttSenderCoordinator. */ + @Binds + @IntoMap + @ClassKey(MediaTttSenderCoordinator::class) + abstract fun bindMediaTttSenderCoordinator(sysui: MediaTttSenderCoordinator): CoreStartable + /** Inject into MediaTttChipControllerReceiver. */ @Binds @IntoMap @@ -225,17 +232,15 @@ abstract class SystemUICoreStartableModule { 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 66c036cee6009..a8a84331050d0 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.nearby.NearbyMediaDevicesManager; 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 @@ public interface MediaModule { return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager); } - /** */ - @Provides - @SysUISingleton - static Optional providesMediaTttChipControllerSender( - MediaTttFlags mediaTttFlags, - Lazy controllerSenderLazy) { - if (!mediaTttFlags.isMediaTttEnabled()) { - return Optional.empty(); - } - return Optional.of(controllerSenderLazy.get()); - } - - /** */ - @Provides - @SysUISingleton - static Optional providesMediaTttChipControllerReceiver( - MediaTttFlags mediaTttFlags, - Lazy 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 6379960b85e96..b5a0483e0c69e 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 @@ in the `receiver` package, and code that's shared between them is in the `common ## 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 1461293c7a075..089625ca8d9c3 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.settingslib.Utils 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 @@ -52,6 +53,8 @@ import javax.inject.Inject * A controller to display and hide the Media Tap-To-Transfer chip on the **receiving** device. * * This chip is shown when a user is transferring media to/from a sending device and this device. + * + * TODO(b/245610654): Re-name this to be MediaTttReceiverCoordinator. */ @SysUISingleton class MediaTttChipControllerReceiver @Inject constructor( @@ -64,6 +67,7 @@ class MediaTttChipControllerReceiver @Inject constructor( configurationController: ConfigurationController, powerManager: PowerManager, @Main private val mainHandler: Handler, + private val mediaTttFlags: MediaTttFlags, private val uiEventLogger: MediaTttReceiverUiEventLogger, private val viewUtil: ViewUtil, ) : TemporaryViewDisplayController( @@ -118,7 +122,7 @@ class MediaTttChipControllerReceiver @Inject constructor( uiEventLogger.logReceiverStateChange(chipState) if (chipState == ChipStateReceiver.FAR_FROM_SENDER) { - removeView(removalReason = ChipStateReceiver.FAR_FROM_SENDER::class.simpleName!!) + removeView(removalReason = ChipStateReceiver.FAR_FROM_SENDER.name) return } if (appIcon == null) { @@ -138,7 +142,9 @@ class MediaTttChipControllerReceiver @Inject constructor( } 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 aae973dcc1c7d..c24b0307fcd17 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.internal.statusbar.IUndoMediaTransferCallback 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 @@ enum class ChipStateSender( transferStatus = TransferStatus.SUCCEEDED, ) { override fun undoClickListener( - controllerSender: MediaTttChipControllerSender, + chipbarCoordinator: ChipbarCoordinator, routeInfo: MediaRoute2Info, undoCallback: IUndoMediaTransferCallback?, uiEventLogger: MediaTttSenderUiEventLogger, @@ -123,9 +125,9 @@ enum class ChipStateSender( 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 @@ enum class ChipStateSender( transferStatus = TransferStatus.SUCCEEDED, ) { override fun undoClickListener( - controllerSender: MediaTttChipControllerSender, + chipbarCoordinator: ChipbarCoordinator, routeInfo: MediaRoute2Info, undoCallback: IUndoMediaTransferCallback?, uiEventLogger: MediaTttSenderUiEventLogger, @@ -164,7 +166,7 @@ enum class ChipStateSender( // 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 @@ enum class ChipStateSender( * 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/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt new file mode 100644 index 0000000000000..5aaab14c1065e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2022 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.media.taptotransfer.sender + +import android.app.StatusBarManager +import android.content.Context +import android.media.MediaRoute2Info +import android.util.Log +import com.android.internal.statusbar.IUndoMediaTransferCallback +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.SysUISingleton +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.temporarydisplay.chipbar.ChipSenderInfo +import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator +import com.android.systemui.temporarydisplay.chipbar.SENDER_TAG +import javax.inject.Inject + +/** + * A coordinator for showing/hiding the Media Tap-To-Transfer UI on the **sending** device. This UI + * is shown when a user is transferring media to/from this device and a receiver device. + */ +@SysUISingleton +class MediaTttSenderCoordinator +@Inject +constructor( + private val chipbarCoordinator: ChipbarCoordinator, + private val commandQueue: CommandQueue, + private val context: Context, + @MediaTttSenderLogger private val logger: MediaTttLogger, + private val mediaTttFlags: MediaTttFlags, + private val uiEventLogger: MediaTttSenderUiEventLogger, +) : CoreStartable { + + private val commandQueueCallbacks = + object : CommandQueue.Callbacks { + override fun updateMediaTapToTransferSenderDisplay( + @StatusBarManager.MediaTransferSenderState displayState: Int, + routeInfo: MediaRoute2Info, + undoCallback: IUndoMediaTransferCallback? + ) { + this@MediaTttSenderCoordinator.updateMediaTapToTransferSenderDisplay( + displayState, + routeInfo, + undoCallback + ) + } + } + + override fun start() { + if (mediaTttFlags.isMediaTttEnabled()) { + commandQueue.addCallback(commandQueueCallbacks) + } + } + + private fun updateMediaTapToTransferSenderDisplay( + @StatusBarManager.MediaTransferSenderState displayState: Int, + routeInfo: MediaRoute2Info, + undoCallback: IUndoMediaTransferCallback? + ) { + val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState) + val stateName = chipState?.name ?: "Invalid" + logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName) + + if (chipState == null) { + Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState") + return + } + uiEventLogger.logSenderStateChange(chipState) + + if (chipState == ChipStateSender.FAR_FROM_RECEIVER) { + chipbarCoordinator.removeView(removalReason = ChipStateSender.FAR_FROM_RECEIVER.name) + } else { + chipbarCoordinator.displayView(ChipSenderInfo(chipState, routeInfo, undoCallback)) + } + } +} 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 78% 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 ca066f472c0ce..a2cd1420a41c0 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,14 +14,12 @@ * 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 import android.graphics.Rect import android.media.MediaRoute2Info import android.os.PowerManager -import android.util.Log import android.view.Gravity import android.view.MotionEvent import android.view.View @@ -40,8 +38,11 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main 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 import com.android.systemui.temporarydisplay.TemporaryDisplayRemovalReason import com.android.systemui.temporarydisplay.TemporaryViewDisplayController @@ -51,12 +52,26 @@ import com.android.systemui.util.view.ViewUtil 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( - private val commandQueue: CommandQueue, +open class ChipbarCoordinator @Inject constructor( context: Context, @MediaTttSenderLogger logger: MediaTttLogger, windowManager: WindowManager, @@ -76,59 +91,25 @@ open class MediaTttChipControllerSender @Inject constructor( 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) } - private val commandQueueCallbacks = object : CommandQueue.Callbacks { - override fun updateMediaTapToTransferSenderDisplay( - @StatusBarManager.MediaTransferSenderState displayState: Int, - routeInfo: MediaRoute2Info, - undoCallback: IUndoMediaTransferCallback? - ) { - this@MediaTttChipControllerSender.updateMediaTapToTransferSenderDisplay( - displayState, routeInfo, undoCallback - ) - } - } - - private fun updateMediaTapToTransferSenderDisplay( - @StatusBarManager.MediaTransferSenderState displayState: Int, - routeInfo: MediaRoute2Info, - undoCallback: IUndoMediaTransferCallback? - ) { - val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState) - val stateName = chipState?.name ?: "Invalid" - logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName) - - if (chipState == null) { - Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState") - return - } - uiEventLogger.logSenderStateChange(chipState) - - if (chipState == ChipStateSender.FAR_FROM_RECEIVER) { - removeView(removalReason = ChipStateSender.FAR_FROM_RECEIVER.name) - } else { - displayView(ChipSenderInfo(chipState, routeInfo, undoCallback)) - } - } - - override fun start() { - commandQueue.addCallback(commandQueueCallbacks) - } + override fun start() {} override fun updateView( newInfo: ChipSenderInfo, currentView: ViewGroup ) { + // TODO(b/245610654): Adding logging here. + val chipState = newInfo.state // Detect falsing touches on the chip. 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 3373159fba4e6..edec420bc4086 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.view.MotionEvent 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 9577274eef8d0..8c3ae3d01f1d2 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 androidx.test.filters.SmallTest 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.junit.runner.RunWith 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 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { @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 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { @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 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { configurationController, powerManager, Handler.getMain(), + mediaTttFlags, receiverUiEventLogger, viewUtil, ) @@ -117,6 +123,30 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { commandQueueCallback = callbackCaptor.value!! } + @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" diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt new file mode 100644 index 0000000000000..616a349520ee9 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2022 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.media.taptotransfer.sender + +import android.app.StatusBarManager +import android.media.MediaRoute2Info +import android.os.PowerManager +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.view.accessibility.AccessibilityManager +import android.widget.TextView +import androidx.test.filters.SmallTest +import com.android.internal.logging.testing.UiEventLoggerFake +import com.android.internal.statusbar.IUndoMediaTransferCallback +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.plugins.FalsingManager +import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.temporarydisplay.chipbar.ChipSenderInfo +import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator +import com.android.systemui.temporarydisplay.chipbar.FakeChipbarCoordinator +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.any +import com.android.systemui.util.time.FakeSystemClock +import com.android.systemui.util.view.ViewUtil +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +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 + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +class MediaTttSenderCoordinatorTest : SysuiTestCase() { + private lateinit var underTest: MediaTttSenderCoordinator + + @Mock private lateinit var accessibilityManager: AccessibilityManager + @Mock private lateinit var commandQueue: CommandQueue + @Mock private lateinit var configurationController: ConfigurationController + @Mock private lateinit var falsingManager: FalsingManager + @Mock private lateinit var falsingCollector: FalsingCollector + @Mock private lateinit var logger: MediaTttLogger + @Mock private lateinit var mediaTttFlags: MediaTttFlags + @Mock private lateinit var powerManager: PowerManager + @Mock private lateinit var viewUtil: ViewUtil + @Mock private lateinit var windowManager: WindowManager + private lateinit var chipbarCoordinator: ChipbarCoordinator + private lateinit var commandQueueCallback: CommandQueue.Callbacks + private lateinit var fakeClock: FakeSystemClock + private lateinit var fakeExecutor: FakeExecutor + private lateinit var uiEventLoggerFake: UiEventLoggerFake + private lateinit var uiEventLogger: MediaTttSenderUiEventLogger + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(true) + whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any())).thenReturn(1000) + + fakeClock = FakeSystemClock() + fakeExecutor = FakeExecutor(fakeClock) + + uiEventLoggerFake = UiEventLoggerFake() + uiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake) + + chipbarCoordinator = + FakeChipbarCoordinator( + context, + logger, + windowManager, + fakeExecutor, + accessibilityManager, + configurationController, + powerManager, + uiEventLogger, + falsingManager, + falsingCollector, + viewUtil, + ) + chipbarCoordinator.start() + + underTest = + MediaTttSenderCoordinator( + chipbarCoordinator, + commandQueue, + context, + logger, + mediaTttFlags, + uiEventLogger, + ) + underTest.start() + + val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java) + verify(commandQueue).addCallback(callbackCaptor.capture()) + commandQueueCallback = callbackCaptor.value!! + } + + @Test + fun commandQueueCallback_flagOff_noCallbackAdded() { + reset(commandQueue) + whenever(mediaTttFlags.isMediaTttEnabled()).thenReturn(false) + underTest = + MediaTttSenderCoordinator( + chipbarCoordinator, + commandQueue, + context, + logger, + mediaTttFlags, + uiEventLogger, + ) + underTest.start() + + verify(commandQueue, never()).addCallback(any()) + } + + @Test + fun commandQueueCallback_almostCloseToStartCast_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo(almostCloseToStartCast().state.getChipTextString(context, OTHER_DEVICE_NAME)) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id) + } + + @Test + fun commandQueueCallback_almostCloseToEndCast_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo(almostCloseToEndCast().state.getChipTextString(context, OTHER_DEVICE_NAME)) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id) + } + + @Test + fun commandQueueCallback_transferToReceiverTriggered_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo( + transferToReceiverTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME) + ) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id) + } + + @Test + fun commandQueueCallback_transferToThisDeviceTriggered_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo( + transferToThisDeviceTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME) + ) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id) + } + + @Test + fun commandQueueCallback_transferToReceiverSucceeded_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo( + transferToReceiverSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME) + ) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id) + } + + @Test + fun commandQueueCallback_transferToThisDeviceSucceeded_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo( + transferToThisDeviceSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME) + ) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id) + } + + @Test + fun commandQueueCallback_transferToReceiverFailed_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo( + transferToReceiverFailed().state.getChipTextString(context, OTHER_DEVICE_NAME) + ) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id) + } + + @Test + fun commandQueueCallback_transferToThisDeviceFailed_triggersCorrectChip() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, + routeInfo, + null + ) + + assertThat(getChipView().getChipText()) + .isEqualTo( + transferToThisDeviceFailed().state.getChipTextString(context, OTHER_DEVICE_NAME) + ) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id) + } + + @Test + fun commandQueueCallback_farFromReceiver_noChipShown() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, + routeInfo, + null + ) + + verify(windowManager, never()).addView(any(), any()) + assertThat(uiEventLoggerFake.eventId(0)) + .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER.id) + } + + @Test + fun commandQueueCallback_almostCloseThenFarFromReceiver_chipShownThenHidden() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, + routeInfo, + null + ) + + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, + routeInfo, + null + ) + + val viewCaptor = ArgumentCaptor.forClass(View::class.java) + verify(windowManager).addView(viewCaptor.capture(), any()) + verify(windowManager).removeView(viewCaptor.value) + } + + @Test + fun commandQueueCallback_invalidStateParam_noChipShown() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay(100, routeInfo, null) + + verify(windowManager, never()).addView(any(), any()) + } + + @Test + fun receivesNewStateFromCommandQueue_isLogged() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, + routeInfo, + null + ) + + verify(logger).logStateChange(any(), any(), any()) + } + + @Test + fun transferToReceiverTriggeredThenFarFromReceiver_viewStillDisplayed() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, + routeInfo, + null + ) + + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, + routeInfo, + null + ) + fakeExecutor.runAllReady() + + verify(windowManager, never()).removeView(any()) + verify(logger).logRemovalBypass(any(), any()) + } + + @Test + fun transferToThisDeviceTriggeredThenFarFromReceiver_viewStillDisplayed() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, + routeInfo, + null + ) + + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, + routeInfo, + null + ) + fakeExecutor.runAllReady() + + verify(windowManager, never()).removeView(any()) + verify(logger).logRemovalBypass(any(), any()) + } + + @Test + fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayed() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, + routeInfo, + null + ) + + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, + routeInfo, + null + ) + fakeExecutor.runAllReady() + + verify(windowManager, never()).removeView(any()) + verify(logger).logRemovalBypass(any(), any()) + } + + @Test + fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayed() { + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, + routeInfo, + null + ) + + commandQueueCallback.updateMediaTapToTransferSenderDisplay( + StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, + routeInfo, + null + ) + fakeExecutor.runAllReady() + + verify(windowManager, never()).removeView(any()) + verify(logger).logRemovalBypass(any(), any()) + } + + private fun getChipView(): ViewGroup { + val viewCaptor = ArgumentCaptor.forClass(View::class.java) + verify(windowManager).addView(viewCaptor.capture(), any()) + return viewCaptor.value as ViewGroup + } + + private fun ViewGroup.getChipText(): String = + (this.requireViewById(R.id.text)).text as String + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun almostCloseToStartCast() = + ChipSenderInfo(ChipStateSender.ALMOST_CLOSE_TO_START_CAST, routeInfo) + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun almostCloseToEndCast() = + ChipSenderInfo(ChipStateSender.ALMOST_CLOSE_TO_END_CAST, routeInfo) + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun transferToReceiverTriggered() = + ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo) + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun transferToThisDeviceTriggered() = + ChipSenderInfo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo) + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun transferToReceiverSucceeded(undoCallback: IUndoMediaTransferCallback? = null) = + ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, undoCallback) + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun transferToThisDeviceSucceeded(undoCallback: IUndoMediaTransferCallback? = null) = + ChipSenderInfo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, undoCallback) + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun transferToReceiverFailed() = + ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo) + + /** Helper method providing default parameters to not clutter up the tests. */ + private fun transferToThisDeviceFailed() = + ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo) +} + +private const val OTHER_DEVICE_NAME = "My Tablet" + +private val routeInfo = + MediaRoute2Info.Builder("id", OTHER_DEVICE_NAME) + .addFeature("feature") + .setClientPackageName("com.android.systemui") + .build() 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 c4abedd0eed4c..b10aa125c69d6 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 @@ class TemporaryViewDisplayControllerTest : SysuiTestCase() { 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 59% 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 3a8a51d42f77c..2af48021d0994 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,10 +14,8 @@ * 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 import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.graphics.drawable.Drawable @@ -38,11 +36,11 @@ import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector 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 -import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq @@ -63,8 +61,8 @@ import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) @TestableLooper.RunWithLooper -class MediaTttChipControllerSenderTest : SysuiTestCase() { - private lateinit var controllerSender: TestMediaTttChipControllerSender +class ChipbarCoordinatorTest : SysuiTestCase() { + private lateinit var underTest: FakeChipbarCoordinator @Mock private lateinit var packageManager: PackageManager @@ -81,14 +79,11 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @Mock private lateinit var windowManager: WindowManager @Mock - private lateinit var commandQueue: CommandQueue - @Mock private lateinit var falsingManager: FalsingManager @Mock private lateinit var falsingCollector: FalsingCollector @Mock private lateinit var viewUtil: ViewUtil - private lateinit var commandQueueCallback: CommandQueue.Callbacks private lateinit var fakeAppIconDrawable: Drawable private lateinit var fakeClock: FakeSystemClock private lateinit var fakeExecutor: FakeExecutor @@ -115,8 +110,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any())).thenReturn(TIMEOUT) - controllerSender = TestMediaTttChipControllerSender( - commandQueue, + underTest = FakeChipbarCoordinator( context, logger, windowManager, @@ -129,200 +123,13 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { falsingCollector, viewUtil, ) - controllerSender.start() - - val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java) - verify(commandQueue).addCallback(callbackCaptor.capture()) - commandQueueCallback = callbackCaptor.value!! - } - - @Test - fun commandQueueCallback_almostCloseToStartCast_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - almostCloseToStartCast().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST.id - ) - } - - @Test - fun commandQueueCallback_almostCloseToEndCast_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - almostCloseToEndCast().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST.id - ) - } - - @Test - fun commandQueueCallback_transferToReceiverTriggered_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - transferToReceiverTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED.id - ) - } - - @Test - fun commandQueueCallback_transferToThisDeviceTriggered_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - transferToThisDeviceTriggered().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED.id - ) - } - - @Test - fun commandQueueCallback_transferToReceiverSucceeded_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - transferToReceiverSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id - ) - } - - @Test - fun commandQueueCallback_transferToThisDeviceSucceeded_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - transferToThisDeviceSucceeded().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id - ) - } - - @Test - fun commandQueueCallback_transferToReceiverFailed_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - transferToReceiverFailed().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id - ) - } - - @Test - fun commandQueueCallback_transferToThisDeviceFailed_triggersCorrectChip() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, - routeInfo, - null - ) - - assertThat(getChipView().getChipText()).isEqualTo( - transferToThisDeviceFailed().state.getChipTextString(context, OTHER_DEVICE_NAME) - ) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id - ) - } - - @Test - fun commandQueueCallback_farFromReceiver_noChipShown() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, - routeInfo, - null - ) - - verify(windowManager, never()).addView(any(), any()) - assertThat(uiEventLoggerFake.eventId(0)).isEqualTo( - MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER.id - ) - } - - @Test - fun commandQueueCallback_almostCloseThenFarFromReceiver_chipShownThenHidden() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, - routeInfo, - null - ) - - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, - routeInfo, - null - ) - - val viewCaptor = ArgumentCaptor.forClass(View::class.java) - verify(windowManager).addView(viewCaptor.capture(), any()) - verify(windowManager).removeView(viewCaptor.value) - } - - @Test - fun commandQueueCallback_invalidStateParam_noChipShown() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - 100, - routeInfo, - null - ) - - verify(windowManager, never()).addView(any(), any()) - } - - @Test - fun receivesNewStateFromCommandQueue_isLogged() { - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, - routeInfo, - null - ) - - verify(logger).logStateChange(any(), any(), any()) + underTest.start() } @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 +145,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +161,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +177,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +193,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +207,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +218,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { 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 +234,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { } } - controllerSender.displayView(transferToReceiverSucceeded(undoCallback)) + underTest.displayView(transferToReceiverSucceeded(undoCallback)) getChipView().getUndoButton().performClick() assertThat(undoCallbackCalled).isTrue() @@ -443,7 +250,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { } } - controllerSender.displayView(transferToReceiverSucceeded(undoCallback)) + underTest.displayView(transferToReceiverSucceeded(undoCallback)) getChipView().getUndoButton().performClick() assertThat(undoCallbackCalled).isFalse() @@ -459,7 +266,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { } } - controllerSender.displayView(transferToReceiverSucceeded(undoCallback)) + underTest.displayView(transferToReceiverSucceeded(undoCallback)) getChipView().getUndoButton().performClick() assertThat(undoCallbackCalled).isTrue() @@ -470,7 +277,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { val undoCallback = object : IUndoMediaTransferCallback.Stub() { override fun onUndoTriggered() {} } - controllerSender.displayView(transferToReceiverSucceeded(undoCallback)) + underTest.displayView(transferToReceiverSucceeded(undoCallback)) getChipView().getUndoButton().performClick() @@ -485,7 +292,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +306,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +317,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { 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 +333,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { } } - controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback)) + underTest.displayView(transferToThisDeviceSucceeded(undoCallback)) getChipView().getUndoButton().performClick() assertThat(undoCallbackCalled).isTrue() @@ -537,7 +344,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { val undoCallback = object : IUndoMediaTransferCallback.Stub() { override fun onUndoTriggered() {} } - controllerSender.displayView(transferToThisDeviceSucceeded(undoCallback)) + underTest.displayView(transferToThisDeviceSucceeded(undoCallback)) getChipView().getUndoButton().performClick() @@ -552,7 +359,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +375,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +390,24 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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,41 +420,26 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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") - fakeExecutor.runAllReady() - - verify(windowManager, never()).removeView(any()) - verify(logger).logRemovalBypass(any(), any()) - } - - @Test - fun transferToReceiverTriggeredThenFarFromReceiver_viewStillDisplayed() { - controllerSender.displayView(transferToReceiverTriggered()) - - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, - routeInfo, - null - ) + underTest.removeView("fakeRemovalReason") fakeExecutor.runAllReady() verify(windowManager, never()).removeView(any()) @@ -656,9 +448,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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 +458,10 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @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,34 +470,19 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @Test fun transferToThisDeviceTriggeredThenRemoveView_eventuallyTimesOut() { - controllerSender.displayView(transferToThisDeviceTriggered()) + underTest.displayView(transferToThisDeviceTriggered()) - controllerSender.removeView("fakeRemovalReason") + underTest.removeView("fakeRemovalReason") fakeClock.advanceTime(TIMEOUT + 1L) verify(windowManager).removeView(any()) } - @Test - fun transferToThisDeviceTriggeredThenFarFromReceiver_viewStillDisplayed() { - controllerSender.displayView(transferToThisDeviceTriggered()) - - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, - routeInfo, - null - ) - fakeExecutor.runAllReady() - - verify(windowManager, never()).removeView(any()) - verify(logger).logRemovalBypass(any(), any()) - } - @Test fun transferToReceiverSucceededThenRemoveView_viewStillDisplayed() { - controllerSender.displayView(transferToReceiverSucceeded()) + underTest.displayView(transferToReceiverSucceeded()) - controllerSender.removeView("fakeRemovalReason") + underTest.removeView("fakeRemovalReason") fakeExecutor.runAllReady() verify(windowManager, never()).removeView(any()) @@ -714,34 +491,19 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @Test fun transferToReceiverSucceededThenRemoveView_eventuallyTimesOut() { - controllerSender.displayView(transferToReceiverSucceeded()) + underTest.displayView(transferToReceiverSucceeded()) - controllerSender.removeView("fakeRemovalReason") + underTest.removeView("fakeRemovalReason") fakeClock.advanceTime(TIMEOUT + 1L) verify(windowManager).removeView(any()) } - @Test - fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayed() { - controllerSender.displayView(transferToReceiverSucceeded()) - - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, - routeInfo, - null - ) - fakeExecutor.runAllReady() - - verify(windowManager, never()).removeView(any()) - verify(logger).logRemovalBypass(any(), any()) - } - @Test fun transferToThisDeviceSucceededThenRemoveView_viewStillDisplayed() { - controllerSender.displayView(transferToThisDeviceSucceeded()) + underTest.displayView(transferToThisDeviceSucceeded()) - controllerSender.removeView("fakeRemovalReason") + underTest.removeView("fakeRemovalReason") fakeExecutor.runAllReady() verify(windowManager, never()).removeView(any()) @@ -750,29 +512,14 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceededThenRemoveView_eventuallyTimesOut() { - controllerSender.displayView(transferToThisDeviceSucceeded()) + underTest.displayView(transferToThisDeviceSucceeded()) - controllerSender.removeView("fakeRemovalReason") + underTest.removeView("fakeRemovalReason") fakeClock.advanceTime(TIMEOUT + 1L) verify(windowManager).removeView(any()) } - @Test - fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayed() { - controllerSender.displayView(transferToThisDeviceSucceeded()) - - commandQueueCallback.updateMediaTapToTransferSenderDisplay( - StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, - routeInfo, - null - ) - fakeExecutor.runAllReady() - - verify(windowManager, never()).removeView(any()) - verify(logger).logRemovalBypass(any(), any()) - } - private fun ViewGroup.getAppIconView() = this.requireViewById(R.id.app_icon) private fun ViewGroup.getChipText(): String = @@ -791,6 +538,10 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { return viewCaptor.value as ViewGroup } + // TODO(b/245610654): For now, the below methods are duplicated between this test and + // [MediaTttSenderCoordinatorTest]. Once we define a generic API for [ChipbarCoordinator], + // these will no longer be duplicated. + /** Helper method providing default parameters to not clutter up the tests. */ private fun almostCloseToStartCast() = ChipSenderInfo(ChipStateSender.ALMOST_CLOSE_TO_START_CAST, routeInfo) @@ -822,39 +573,6 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { /** Helper method providing default parameters to not clutter up the tests. */ private fun transferToThisDeviceFailed() = ChipSenderInfo(ChipStateSender.TRANSFER_TO_RECEIVER_FAILED, routeInfo) - - private class TestMediaTttChipControllerSender( - commandQueue: CommandQueue, - context: Context, - @MediaTttReceiverLogger logger: MediaTttLogger, - windowManager: WindowManager, - mainExecutor: DelayableExecutor, - accessibilityManager: AccessibilityManager, - configurationController: ConfigurationController, - powerManager: PowerManager, - uiEventLogger: MediaTttSenderUiEventLogger, - falsingManager: FalsingManager, - falsingCollector: FalsingCollector, - viewUtil: ViewUtil, - ) : MediaTttChipControllerSender( - commandQueue, - context, - logger, - windowManager, - mainExecutor, - accessibilityManager, - configurationController, - powerManager, - uiEventLogger, - falsingManager, - falsingCollector, - viewUtil, - ) { - override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) { - // Just bypass the animation in tests - onAnimationEnd.run() - } - } } private const val APP_NAME = "Fake app name" diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt new file mode 100644 index 0000000000000..10704ac8fc679 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/FakeChipbarCoordinator.kt @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 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.temporarydisplay.chipbar + +import android.content.Context +import android.os.PowerManager +import android.view.ViewGroup +import android.view.WindowManager +import android.view.accessibility.AccessibilityManager +import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.media.taptotransfer.common.MediaTttLogger +import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger +import com.android.systemui.media.taptotransfer.sender.MediaTttSenderUiEventLogger +import com.android.systemui.plugins.FalsingManager +import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.util.concurrency.DelayableExecutor +import com.android.systemui.util.view.ViewUtil + +/** A fake implementation of [ChipbarCoordinator] for testing. */ +class FakeChipbarCoordinator( + context: Context, + @MediaTttReceiverLogger logger: MediaTttLogger, + windowManager: WindowManager, + mainExecutor: DelayableExecutor, + accessibilityManager: AccessibilityManager, + configurationController: ConfigurationController, + powerManager: PowerManager, + uiEventLogger: MediaTttSenderUiEventLogger, + falsingManager: FalsingManager, + falsingCollector: FalsingCollector, + viewUtil: ViewUtil, +) : + ChipbarCoordinator( + context, + logger, + windowManager, + mainExecutor, + accessibilityManager, + configurationController, + powerManager, + uiEventLogger, + falsingManager, + falsingCollector, + viewUtil, + ) { + override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) { + // Just bypass the animation in tests + onAnimationEnd.run() + } +}