[Media TTT] Handle invalid chip transitions

Adds a check for valid transitions for each device before updating the
states. And logs an error if the transition is invalid.

Bug: 221265848
Test: atest MediaTttSenderCoordinatorTest
Change-Id: I98866dc7096fb6400d321629b83bda8e730328a6
This commit is contained in:
Michael Mikhail
2022-12-01 16:35:15 +00:00
parent 1549391e56
commit e99f754094
5 changed files with 346 additions and 19 deletions

View File

@@ -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(

View File

@@ -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
@@ -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
@@ -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
@@ -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.
@@ -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.
@@ -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(
@@ -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(
@@ -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(
@@ -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
}
};
/**
@@ -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
@@ -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)
}
}
}

View File

@@ -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 {
@@ -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
@@ -119,7 +134,7 @@ constructor(
context,
logger,
)
)
) { stateMap.remove(routeInfo.id) }
}
}

View File

@@ -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
@@ -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()
)
}

View File

@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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())
@@ -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,
@@ -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,
@@ -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,
@@ -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,
@@ -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
)
@@ -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,
@@ -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,
@@ -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>())
}
@@ -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(
@@ -575,6 +759,7 @@ class MediaTttSenderCoordinatorTest : SysuiTestCase() {
@Test
fun transferToReceiverSucceededThenFarFromReceiver_viewStillDisplayedButDoesTimeOut() {
displayReceiverTriggered()
commandQueueCallback.updateMediaTapToTransferSenderDisplay(
StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
routeInfo,
@@ -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,
@@ -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,
@@ -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,
@@ -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"