Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d776d63 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[Media TTT] Ignore the FAR_FROM_RECEIVER event if we're in the succeeded

state.

Fixes: 246219284
Test: TRANSFER_SUCCEEDED event then FAR_FROM_RECEIVER event -> chip
still displayed
Test: ALMOST_CLOSE event then FAR_FROM_RECEIVER event -> chip disappears
Test: MediaTttChipControllerSenderTest

Change-Id: I5f21d73799e17f19a11e318113574123f09e89ee
parent fb01c569
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -34,8 +34,7 @@ import com.android.systemui.temporarydisplay.DEFAULT_TIMEOUT_MILLIS
 * @property stateInt the integer from [StatusBarManager] corresponding with this state.
 * @property stringResId the res ID of the string that should be displayed in the chip. Null if the
 *   state should not have the chip be displayed.
 * @property isMidTransfer true if the state represents that a transfer is currently ongoing.
 * @property isTransferFailure true if the state represents that the transfer has failed.
 * @property transferStatus the transfer status that the chip state represents.
 * @property timeout the amount of time this chip should display on the screen before it times out
 *   and disappears.
 */
@@ -43,8 +42,7 @@ enum class ChipStateSender(
    @StatusBarManager.MediaTransferSenderState val stateInt: Int,
    val uiEvent: UiEventLogger.UiEventEnum,
    @StringRes val stringResId: Int?,
    val isMidTransfer: Boolean = false,
    val isTransferFailure: Boolean = false,
    val transferStatus: TransferStatus,
    val timeout: Long = DEFAULT_TIMEOUT_MILLIS
) {
    /**
@@ -56,6 +54,7 @@ enum class ChipStateSender(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST,
        R.string.media_move_closer_to_start_cast,
        transferStatus = TransferStatus.NOT_STARTED,
    ),

    /**
@@ -68,6 +67,7 @@ enum class ChipStateSender(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST,
        R.string.media_move_closer_to_end_cast,
        transferStatus = TransferStatus.NOT_STARTED,
    ),

    /**
@@ -78,7 +78,7 @@ enum class ChipStateSender(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED,
        R.string.media_transfer_playing_different_device,
        isMidTransfer = true,
        transferStatus = TransferStatus.IN_PROGRESS,
        timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
    ),

@@ -90,7 +90,7 @@ enum class ChipStateSender(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
        R.string.media_transfer_playing_this_device,
        isMidTransfer = true,
        transferStatus = TransferStatus.IN_PROGRESS,
        timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS
    ),

@@ -100,7 +100,8 @@ enum class ChipStateSender(
    TRANSFER_TO_RECEIVER_SUCCEEDED(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED,
        R.string.media_transfer_playing_different_device
        R.string.media_transfer_playing_different_device,
        transferStatus = TransferStatus.SUCCEEDED,
    ) {
        override fun undoClickListener(
            controllerSender: MediaTttChipControllerSender,
@@ -135,7 +136,8 @@ enum class ChipStateSender(
    TRANSFER_TO_THIS_DEVICE_SUCCEEDED(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
        R.string.media_transfer_playing_this_device
        R.string.media_transfer_playing_this_device,
        transferStatus = TransferStatus.SUCCEEDED,
    ) {
        override fun undoClickListener(
            controllerSender: MediaTttChipControllerSender,
@@ -169,7 +171,7 @@ enum class ChipStateSender(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED,
        R.string.media_transfer_failed,
        isTransferFailure = true
        transferStatus = TransferStatus.FAILED,
    ),

    /** A state representing that a transfer back to this device has failed. */
@@ -177,14 +179,15 @@ enum class ChipStateSender(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED,
        R.string.media_transfer_failed,
        isTransferFailure = true
        transferStatus = TransferStatus.FAILED,
    ),

    /** A state representing that this device is far away from any receiver device. */
    FAR_FROM_RECEIVER(
        StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
        MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER,
        stringResId = null
        stringResId = null,
        transferStatus = TransferStatus.TOO_FAR,
    );

    /**
+10 −6
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ class MediaTttChipControllerSender @Inject constructor(

        // Loading
        currentView.requireViewById<View>(R.id.loading).visibility =
            chipState.isMidTransfer.visibleIfTrue()
            (chipState.transferStatus == TransferStatus.IN_PROGRESS).visibleIfTrue()

        // Undo
        val undoView = currentView.requireViewById<View>(R.id.undo)
@@ -147,7 +147,7 @@ class MediaTttChipControllerSender @Inject constructor(

        // Failure
        currentView.requireViewById<View>(R.id.failure_icon).visibility =
            chipState.isTransferFailure.visibleIfTrue()
            (chipState.transferStatus == TransferStatus.FAILED).visibleIfTrue()

        // For accessibility
        currentView.requireViewById<ViewGroup>(
@@ -170,10 +170,14 @@ class MediaTttChipControllerSender @Inject constructor(
    }

    override fun removeView(removalReason: String) {
        // Don't remove the chip if we're mid-transfer since the user should still be able to
        // see the status of the transfer. (But do remove it if it's finally timed out.)
        if (info?.state?.isMidTransfer == true &&
                removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT) {
        // Don't remove the chip if we're in progress or succeeded, since the user should still be
        // able to see the status of the transfer. (But do remove it if it's finally timed out.)
        val transferStatus = info?.state?.transferStatus
        if (
            (transferStatus == TransferStatus.IN_PROGRESS ||
                transferStatus == TransferStatus.SUCCEEDED) &&
            removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT
        ) {
            return
        }
        super.removeView(removalReason)
+31 −0
Original line number Diff line number Diff line
/*
 * 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

/** Represents the different possible transfer states that we could be in. */
enum class TransferStatus {
    /** The transfer hasn't started yet. */
    NOT_STARTED,
    /** The transfer is currently ongoing but hasn't completed yet. */
    IN_PROGRESS,
    /** The transfer has completed successfully. */
    SUCCEEDED,
    /** The transfer has completed with a failure. */
    FAILED,
    /** The device is too far away to do a transfer. */
    TOO_FAR,
}
+101 −9
Original line number Diff line number Diff line
@@ -590,12 +590,24 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
    }

    @Test
    fun transferToReceiverTriggeredThenFarFromReceiver_eventuallyTimesOut() {
        val state = transferToReceiverTriggered()
        controllerSender.displayView(state)
        fakeClock.advanceTime(1000L)
        controllerSender.removeView("fakeRemovalReason")
    fun transferToReceiverTriggeredThenFarFromReceiver_viewStillDisplayed() {
        controllerSender.displayView(transferToReceiverTriggered())

        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER,
            routeInfo,
            null
        )
        fakeExecutor.runAllReady()

        verify(windowManager, never()).removeView(any())
    }

    @Test
    fun transferToReceiverTriggeredThenRemoveView_eventuallyTimesOut() {
        controllerSender.displayView(transferToReceiverTriggered())

        controllerSender.removeView("fakeRemovalReason")
        fakeClock.advanceTime(TIMEOUT + 1L)

        verify(windowManager).removeView(any())
@@ -613,17 +625,97 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
    }

    @Test
    fun transferToThisDeviceTriggeredThenFarFromReceiver_eventuallyTimesOut() {
        val state = transferToThisDeviceTriggered()
        controllerSender.displayView(state)
        fakeClock.advanceTime(1000L)
    fun transferToThisDeviceTriggeredThenRemoveView_eventuallyTimesOut() {
        controllerSender.displayView(transferToThisDeviceTriggered())

        controllerSender.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())
    }

    @Test
    fun transferToReceiverSucceededThenRemoveView_viewStillDisplayed() {
        controllerSender.displayView(transferToReceiverSucceeded())

        controllerSender.removeView("fakeRemovalReason")
        fakeExecutor.runAllReady()

        verify(windowManager, never()).removeView(any())
    }

    @Test
    fun transferToReceiverSucceededThenRemoveView_eventuallyTimesOut() {
        controllerSender.displayView(transferToReceiverSucceeded())

        controllerSender.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())
    }

    @Test
    fun transferToThisDeviceSucceededThenRemoveView_viewStillDisplayed() {
        controllerSender.displayView(transferToThisDeviceSucceeded())

        controllerSender.removeView("fakeRemovalReason")
        fakeExecutor.runAllReady()

        verify(windowManager, never()).removeView(any())
    }

    @Test
    fun transferToThisDeviceSucceededThenRemoveView_eventuallyTimesOut() {
        controllerSender.displayView(transferToThisDeviceSucceeded())

        controllerSender.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())
    }

    private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)

    private fun ViewGroup.getChipText(): String =