Loading packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt +21 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,27 @@ class MediaTttLogger( ) } /** * Logs an invalid sender state transition error in trying to update to [desiredState]. * * @param currentState the previous state of the chip. * @param desiredState the new state of the chip. */ fun logInvalidStateTransitionError( currentState: String, desiredState: String ) { buffer.log( tag, LogLevel.ERROR, { str1 = currentState str2 = desiredState }, { "Cannot display state=$str2 after state=$str1; invalid transition" } ) } /** Logs that we couldn't find information for [packageName]. */ fun logPackageNotFound(packageName: String) { buffer.log( Loading packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +87 −8 Original line number Diff line number Diff line Loading @@ -56,7 +56,12 @@ enum class ChipStateSender( R.string.media_move_closer_to_start_cast, transferStatus = TransferStatus.NOT_STARTED, endItem = null, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_RECEIVER_TRIGGERED } }, /** * A state representing that the two devices are close but not close enough to *end* a cast Loading @@ -70,7 +75,12 @@ enum class ChipStateSender( R.string.media_move_closer_to_end_cast, transferStatus = TransferStatus.NOT_STARTED, endItem = null, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_THIS_DEVICE_TRIGGERED } }, /** * A state representing that a transfer to the receiver device has been initiated (but not Loading @@ -83,7 +93,13 @@ enum class ChipStateSender( transferStatus = TransferStatus.IN_PROGRESS, endItem = SenderEndItem.Loading, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_RECEIVER_SUCCEEDED || nextState == TRANSFER_TO_RECEIVER_FAILED } }, /** * A state representing that a transfer from the receiver device and back to this device (the Loading @@ -96,7 +112,13 @@ enum class ChipStateSender( transferStatus = TransferStatus.IN_PROGRESS, endItem = SenderEndItem.Loading, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_THIS_DEVICE_SUCCEEDED || nextState == TRANSFER_TO_THIS_DEVICE_FAILED } }, /** * A state representing that a transfer to the receiver device has been successfully completed. Loading @@ -112,7 +134,13 @@ enum class ChipStateSender( newState = StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED ), ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_START_CAST || nextState == TRANSFER_TO_THIS_DEVICE_TRIGGERED } }, /** * A state representing that a transfer back to this device has been successfully completed. Loading @@ -128,7 +156,13 @@ enum class ChipStateSender( newState = StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED ), ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_END_CAST || nextState == TRANSFER_TO_RECEIVER_TRIGGERED } }, /** A state representing that a transfer to the receiver device has failed. */ TRANSFER_TO_RECEIVER_FAILED( Loading @@ -137,7 +171,13 @@ enum class ChipStateSender( R.string.media_transfer_failed, transferStatus = TransferStatus.FAILED, endItem = SenderEndItem.Error, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_START_CAST || nextState == TRANSFER_TO_THIS_DEVICE_TRIGGERED } }, /** A state representing that a transfer back to this device has failed. */ TRANSFER_TO_THIS_DEVICE_FAILED( Loading @@ -146,7 +186,13 @@ enum class ChipStateSender( R.string.media_transfer_failed, transferStatus = TransferStatus.FAILED, endItem = SenderEndItem.Error, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_END_CAST || nextState == TRANSFER_TO_RECEIVER_TRIGGERED } }, /** A state representing that this device is far away from any receiver device. */ FAR_FROM_RECEIVER( Loading @@ -162,6 +208,12 @@ enum class ChipStateSender( throw IllegalArgumentException("FAR_FROM_RECEIVER should never be displayed, " + "so its string should never be fetched") } override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState.transferStatus == TransferStatus.NOT_STARTED || nextState.transferStatus == TransferStatus.IN_PROGRESS } }; /** Loading @@ -175,6 +227,8 @@ enum class ChipStateSender( return Text.Loaded(context.getString(stringResId!!, otherDeviceName)) } abstract fun isValidNextState(nextState: ChipStateSender): Boolean companion object { /** * Returns the sender state enum associated with the given [displayState] from Loading @@ -197,6 +251,31 @@ enum class ChipStateSender( */ @StatusBarManager.MediaTransferSenderState fun getSenderStateIdFromName(name: String): Int = valueOf(name).stateInt /** * Validates the transition from a chip state to another. * * @param currentState is the current state of the chip. * @param desiredState is the desired state of the chip. * @return true if the transition from [currentState] to [desiredState] is valid, and false * otherwise. */ fun isValidStateTransition( currentState: ChipStateSender?, desiredState: ChipStateSender, ): Boolean { // Far from receiver is the default state. if (currentState == null) { return FAR_FROM_RECEIVER.isValidNextState(desiredState) } // No change in state is valid. if (currentState == desiredState) { return true } return currentState.isValidNextState(desiredState) } } } Loading packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt +16 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ constructor( ) : CoreStartable { private var displayedState: ChipStateSender? = null // A map to store current chip state per id. private var stateMap: MutableMap<String, ChipStateSender> = mutableMapOf() private val commandQueueCallbacks = object : CommandQueue.Callbacks { Loading Loading @@ -87,9 +89,22 @@ constructor( logger.logStateChangeError(displayState) return } val currentState = stateMap[routeInfo.id] if (!ChipStateSender.isValidStateTransition(currentState, chipState)) { // ChipStateSender.FAR_FROM_RECEIVER is the default state when there is no state. logger.logInvalidStateTransitionError( currentState = currentState?.name ?: ChipStateSender.FAR_FROM_RECEIVER.name, chipState.name ) return } uiEventLogger.logSenderStateChange(chipState) stateMap.put(routeInfo.id, chipState) if (chipState == ChipStateSender.FAR_FROM_RECEIVER) { // No need to store the state since it is the default state stateMap.remove(routeInfo.id) // Return early if we're not displaying a chip anyway val currentDisplayedState = displayedState ?: return Loading Loading @@ -119,7 +134,7 @@ constructor( context, logger, ) ) ) { stateMap.remove(routeInfo.id) } } } Loading packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt +6 −2 Original line number Diff line number Diff line Loading @@ -105,8 +105,9 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora * * This method handles inflating and attaching the view, then delegates to [updateView] to * display the correct information in the view. * @param onViewTimeout a runnable that runs after the view timeout. */ fun displayView(newInfo: T) { fun displayView(newInfo: T, onViewTimeout: Runnable? = null) { val currentDisplayInfo = displayInfo // Update our list of active devices by removing it if necessary, then adding back at the Loading Loading @@ -173,7 +174,10 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora cancelViewTimeout?.run() } cancelViewTimeout = mainExecutor.executeDelayed( { removeView(id, REMOVAL_REASON_TIMEOUT) }, { removeView(id, REMOVAL_REASON_TIMEOUT) onViewTimeout?.run() }, timeout.toLong() ) } Loading packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt +216 −8 Original line number Diff line number Diff line Loading @@ -265,6 +265,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun commandQueueCallback_transferToReceiverSucceeded_triggersCorrectChip() { displayReceiverTriggered() reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -278,13 +280,15 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { .isEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.getExpectedStateText()) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id) verify(vibratorHelper, never()).vibrate(any<VibrationEffect>()) } @Test fun transferToReceiverSucceeded_nullUndoCallback_noUndo() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -297,6 +301,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceeded_withUndoRunnable_undoVisible() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -313,6 +318,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() { var undoCallbackCalled = false displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -325,8 +331,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { getChipbarView().getUndoButton().performClick() // Event index 1 since initially displaying the succeeded chip would also log an event assertThat(uiEventLoggerFake.eventId(1)) // Event index 2 since initially displaying the triggered and succeeded chip would also log // events. assertThat(uiEventLoggerFake.eventId(2)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED.id) assertThat(undoCallbackCalled).isTrue() assertThat(getChipbarView().getChipText()) Loading @@ -335,6 +342,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun commandQueueCallback_transferToThisDeviceSucceeded_triggersCorrectChip() { displayThisDeviceTriggered() reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -348,13 +357,15 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { .isEqualTo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.getExpectedStateText()) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id) verify(vibratorHelper, never()).vibrate(any<VibrationEffect>()) } @Test fun transferToThisDeviceSucceeded_nullUndoCallback_noUndo() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -367,6 +378,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceeded_withUndoRunnable_undoVisible() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -383,6 +395,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() { var undoCallbackCalled = false displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -395,8 +408,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { getChipbarView().getUndoButton().performClick() // Event index 1 since initially displaying the succeeded chip would also log an event assertThat(uiEventLoggerFake.eventId(1)) // Event index 2 since initially displaying the triggered and succeeded chip would also log // events. assertThat(uiEventLoggerFake.eventId(2)) .isEqualTo( MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED.id ) Loading @@ -407,6 +421,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun commandQueueCallback_transferToReceiverFailed_triggersCorrectChip() { displayReceiverTriggered() reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, routeInfo, Loading @@ -421,13 +437,20 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id) verify(vibratorHelper).vibrate(any<VibrationEffect>()) } @Test fun commandQueueCallback_transferToThisDeviceFailed_triggersCorrectChip() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, routeInfo, Loading @@ -442,7 +465,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id) verify(vibratorHelper).vibrate(any<VibrationEffect>()) } Loading Loading @@ -516,6 +540,166 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_receiverTriggeredThenAlmostStart_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_thisDeviceTriggeredThenAlmostEnd_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_receiverSucceededThenReceiverTriggered_invalidTransitionLogged() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, null ) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_thisDeviceSucceededThenThisDeviceTriggered_invalidTransitionLogged() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, null ) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_almostStartThenReceiverSucceeded_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_almostEndThenThisDeviceSucceeded_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_AlmostStartThenReceiverFailed_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_almostEndThenThisDeviceFailed_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun receivesNewStateFromCommandQueue_isLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( Loading Loading @@ -575,6 +759,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -598,6 +783,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -621,6 +807,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceeded_thenUndo_thenFar_viewStillDisplayedButDoesTimeOut() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading Loading @@ -660,6 +847,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceeded_thenUndo_thenFar_viewStillDisplayedButDoesTimeOut() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading Loading @@ -717,6 +905,26 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { private fun ChipStateSender.getExpectedStateText(): String? { return this.getChipTextString(context, OTHER_DEVICE_NAME).loadText(context) } // display receiver triggered state helper method to make sure we start from a valid state // transition (FAR_FROM_RECEIVER -> TRANSFER_TO_RECEIVER_TRIGGERED). private fun displayReceiverTriggered() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, null ) } // display this device triggered state helper method to make sure we start from a valid state // transition (FAR_FROM_RECEIVER -> TRANSFER_TO_THIS_DEVICE_TRIGGERED). private fun displayThisDeviceTriggered() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) } } private const val APP_NAME = "Fake app name" Loading Loading
packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt +21 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,27 @@ class MediaTttLogger( ) } /** * Logs an invalid sender state transition error in trying to update to [desiredState]. * * @param currentState the previous state of the chip. * @param desiredState the new state of the chip. */ fun logInvalidStateTransitionError( currentState: String, desiredState: String ) { buffer.log( tag, LogLevel.ERROR, { str1 = currentState str2 = desiredState }, { "Cannot display state=$str2 after state=$str1; invalid transition" } ) } /** Logs that we couldn't find information for [packageName]. */ fun logPackageNotFound(packageName: String) { buffer.log( Loading
packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +87 −8 Original line number Diff line number Diff line Loading @@ -56,7 +56,12 @@ enum class ChipStateSender( R.string.media_move_closer_to_start_cast, transferStatus = TransferStatus.NOT_STARTED, endItem = null, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_RECEIVER_TRIGGERED } }, /** * A state representing that the two devices are close but not close enough to *end* a cast Loading @@ -70,7 +75,12 @@ enum class ChipStateSender( R.string.media_move_closer_to_end_cast, transferStatus = TransferStatus.NOT_STARTED, endItem = null, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_THIS_DEVICE_TRIGGERED } }, /** * A state representing that a transfer to the receiver device has been initiated (but not Loading @@ -83,7 +93,13 @@ enum class ChipStateSender( transferStatus = TransferStatus.IN_PROGRESS, endItem = SenderEndItem.Loading, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_RECEIVER_SUCCEEDED || nextState == TRANSFER_TO_RECEIVER_FAILED } }, /** * A state representing that a transfer from the receiver device and back to this device (the Loading @@ -96,7 +112,13 @@ enum class ChipStateSender( transferStatus = TransferStatus.IN_PROGRESS, endItem = SenderEndItem.Loading, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == TRANSFER_TO_THIS_DEVICE_SUCCEEDED || nextState == TRANSFER_TO_THIS_DEVICE_FAILED } }, /** * A state representing that a transfer to the receiver device has been successfully completed. Loading @@ -112,7 +134,13 @@ enum class ChipStateSender( newState = StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED ), ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_START_CAST || nextState == TRANSFER_TO_THIS_DEVICE_TRIGGERED } }, /** * A state representing that a transfer back to this device has been successfully completed. Loading @@ -128,7 +156,13 @@ enum class ChipStateSender( newState = StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED ), ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_END_CAST || nextState == TRANSFER_TO_RECEIVER_TRIGGERED } }, /** A state representing that a transfer to the receiver device has failed. */ TRANSFER_TO_RECEIVER_FAILED( Loading @@ -137,7 +171,13 @@ enum class ChipStateSender( R.string.media_transfer_failed, transferStatus = TransferStatus.FAILED, endItem = SenderEndItem.Error, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_START_CAST || nextState == TRANSFER_TO_THIS_DEVICE_TRIGGERED } }, /** A state representing that a transfer back to this device has failed. */ TRANSFER_TO_THIS_DEVICE_FAILED( Loading @@ -146,7 +186,13 @@ enum class ChipStateSender( R.string.media_transfer_failed, transferStatus = TransferStatus.FAILED, endItem = SenderEndItem.Error, ), ) { override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState == ALMOST_CLOSE_TO_END_CAST || nextState == TRANSFER_TO_RECEIVER_TRIGGERED } }, /** A state representing that this device is far away from any receiver device. */ FAR_FROM_RECEIVER( Loading @@ -162,6 +208,12 @@ enum class ChipStateSender( throw IllegalArgumentException("FAR_FROM_RECEIVER should never be displayed, " + "so its string should never be fetched") } override fun isValidNextState(nextState: ChipStateSender): Boolean { return nextState == FAR_FROM_RECEIVER || nextState.transferStatus == TransferStatus.NOT_STARTED || nextState.transferStatus == TransferStatus.IN_PROGRESS } }; /** Loading @@ -175,6 +227,8 @@ enum class ChipStateSender( return Text.Loaded(context.getString(stringResId!!, otherDeviceName)) } abstract fun isValidNextState(nextState: ChipStateSender): Boolean companion object { /** * Returns the sender state enum associated with the given [displayState] from Loading @@ -197,6 +251,31 @@ enum class ChipStateSender( */ @StatusBarManager.MediaTransferSenderState fun getSenderStateIdFromName(name: String): Int = valueOf(name).stateInt /** * Validates the transition from a chip state to another. * * @param currentState is the current state of the chip. * @param desiredState is the desired state of the chip. * @return true if the transition from [currentState] to [desiredState] is valid, and false * otherwise. */ fun isValidStateTransition( currentState: ChipStateSender?, desiredState: ChipStateSender, ): Boolean { // Far from receiver is the default state. if (currentState == null) { return FAR_FROM_RECEIVER.isValidNextState(desiredState) } // No change in state is valid. if (currentState == desiredState) { return true } return currentState.isValidNextState(desiredState) } } } Loading
packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt +16 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ constructor( ) : CoreStartable { private var displayedState: ChipStateSender? = null // A map to store current chip state per id. private var stateMap: MutableMap<String, ChipStateSender> = mutableMapOf() private val commandQueueCallbacks = object : CommandQueue.Callbacks { Loading Loading @@ -87,9 +89,22 @@ constructor( logger.logStateChangeError(displayState) return } val currentState = stateMap[routeInfo.id] if (!ChipStateSender.isValidStateTransition(currentState, chipState)) { // ChipStateSender.FAR_FROM_RECEIVER is the default state when there is no state. logger.logInvalidStateTransitionError( currentState = currentState?.name ?: ChipStateSender.FAR_FROM_RECEIVER.name, chipState.name ) return } uiEventLogger.logSenderStateChange(chipState) stateMap.put(routeInfo.id, chipState) if (chipState == ChipStateSender.FAR_FROM_RECEIVER) { // No need to store the state since it is the default state stateMap.remove(routeInfo.id) // Return early if we're not displaying a chip anyway val currentDisplayedState = displayedState ?: return Loading Loading @@ -119,7 +134,7 @@ constructor( context, logger, ) ) ) { stateMap.remove(routeInfo.id) } } } Loading
packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt +6 −2 Original line number Diff line number Diff line Loading @@ -105,8 +105,9 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora * * This method handles inflating and attaching the view, then delegates to [updateView] to * display the correct information in the view. * @param onViewTimeout a runnable that runs after the view timeout. */ fun displayView(newInfo: T) { fun displayView(newInfo: T, onViewTimeout: Runnable? = null) { val currentDisplayInfo = displayInfo // Update our list of active devices by removing it if necessary, then adding back at the Loading Loading @@ -173,7 +174,10 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora cancelViewTimeout?.run() } cancelViewTimeout = mainExecutor.executeDelayed( { removeView(id, REMOVAL_REASON_TIMEOUT) }, { removeView(id, REMOVAL_REASON_TIMEOUT) onViewTimeout?.run() }, timeout.toLong() ) } Loading
packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinatorTest.kt +216 −8 Original line number Diff line number Diff line Loading @@ -265,6 +265,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun commandQueueCallback_transferToReceiverSucceeded_triggersCorrectChip() { displayReceiverTriggered() reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -278,13 +280,15 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { .isEqualTo(ChipStateSender.TRANSFER_TO_RECEIVER_SUCCEEDED.getExpectedStateText()) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED.id) verify(vibratorHelper, never()).vibrate(any<VibrationEffect>()) } @Test fun transferToReceiverSucceeded_nullUndoCallback_noUndo() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -297,6 +301,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceeded_withUndoRunnable_undoVisible() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -313,6 +318,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() { var undoCallbackCalled = false displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -325,8 +331,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { getChipbarView().getUndoButton().performClick() // Event index 1 since initially displaying the succeeded chip would also log an event assertThat(uiEventLoggerFake.eventId(1)) // Event index 2 since initially displaying the triggered and succeeded chip would also log // events. assertThat(uiEventLoggerFake.eventId(2)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED.id) assertThat(undoCallbackCalled).isTrue() assertThat(getChipbarView().getChipText()) Loading @@ -335,6 +342,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun commandQueueCallback_transferToThisDeviceSucceeded_triggersCorrectChip() { displayThisDeviceTriggered() reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -348,13 +357,15 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { .isEqualTo(ChipStateSender.TRANSFER_TO_THIS_DEVICE_SUCCEEDED.getExpectedStateText()) assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED.id) verify(vibratorHelper, never()).vibrate(any<VibrationEffect>()) } @Test fun transferToThisDeviceSucceeded_nullUndoCallback_noUndo() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -367,6 +378,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceeded_withUndoRunnable_undoVisible() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -383,6 +395,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() { var undoCallbackCalled = false displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -395,8 +408,9 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { getChipbarView().getUndoButton().performClick() // Event index 1 since initially displaying the succeeded chip would also log an event assertThat(uiEventLoggerFake.eventId(1)) // Event index 2 since initially displaying the triggered and succeeded chip would also log // events. assertThat(uiEventLoggerFake.eventId(2)) .isEqualTo( MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED.id ) Loading @@ -407,6 +421,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun commandQueueCallback_transferToReceiverFailed_triggersCorrectChip() { displayReceiverTriggered() reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, routeInfo, Loading @@ -421,13 +437,20 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED.id) verify(vibratorHelper).vibrate(any<VibrationEffect>()) } @Test fun commandQueueCallback_transferToThisDeviceFailed_triggersCorrectChip() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) reset(vibratorHelper) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, routeInfo, Loading @@ -442,7 +465,8 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { assertThat(chipbarView.getLoadingIcon().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getUndoButton().visibility).isEqualTo(View.GONE) assertThat(chipbarView.getErrorIcon().visibility).isEqualTo(View.VISIBLE) assertThat(uiEventLoggerFake.eventId(0)) // Event index 1 since initially displaying the triggered chip would also log an event. assertThat(uiEventLoggerFake.eventId(1)) .isEqualTo(MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED.id) verify(vibratorHelper).vibrate(any<VibrationEffect>()) } Loading Loading @@ -516,6 +540,166 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_receiverTriggeredThenAlmostStart_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_thisDeviceTriggeredThenAlmostEnd_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_receiverSucceededThenReceiverTriggered_invalidTransitionLogged() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, null ) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_thisDeviceSucceededThenThisDeviceTriggered_invalidTransitionLogged() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, null ) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_almostStartThenReceiverSucceeded_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_almostEndThenThisDeviceSucceeded_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_AlmostStartThenReceiverFailed_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun commandQueueCallback_almostEndThenThisDeviceFailed_invalidTransitionLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, routeInfo, null ) verify(windowManager).addView(any(), any()) reset(windowManager) commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, routeInfo, null ) verify(logger).logInvalidStateTransitionError(any(), any()) verify(windowManager, never()).addView(any(), any()) } @Test fun receivesNewStateFromCommandQueue_isLogged() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( Loading Loading @@ -575,6 +759,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading @@ -598,6 +783,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceededThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading @@ -621,6 +807,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToReceiverSucceeded_thenUndo_thenFar_viewStillDisplayedButDoesTimeOut() { displayReceiverTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, routeInfo, Loading Loading @@ -660,6 +847,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { @Test fun transferToThisDeviceSucceeded_thenUndo_thenFar_viewStillDisplayedButDoesTimeOut() { displayThisDeviceTriggered() commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, routeInfo, Loading Loading @@ -717,6 +905,26 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() { private fun ChipStateSender.getExpectedStateText(): String? { return this.getChipTextString(context, OTHER_DEVICE_NAME).loadText(context) } // display receiver triggered state helper method to make sure we start from a valid state // transition (FAR_FROM_RECEIVER -> TRANSFER_TO_RECEIVER_TRIGGERED). private fun displayReceiverTriggered() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, routeInfo, null ) } // display this device triggered state helper method to make sure we start from a valid state // transition (FAR_FROM_RECEIVER -> TRANSFER_TO_THIS_DEVICE_TRIGGERED). private fun displayThisDeviceTriggered() { commandQueueCallback.updateMediaTapToTransferSenderDisplay( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, routeInfo, null ) } } private const val APP_NAME = "Fake app name" Loading