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

Commit 36e9f975 authored by Caitlin Cassidy's avatar Caitlin Cassidy
Browse files

[Media TTT] Add the click listener for the undo button.

Fixes: 203800665
Test: MediaTttChipControllerTest
Test: `adb shell cmd statusbar media-ttt-chip-add Tablet
TransferSucceeded` then tap undo button -> log statement that the undo
runnable was triggered

Change-Id: Iad10917f375e0fc35ca41265533296a67485e0ba
parent e1902d9e
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.media.taptotransfer

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PixelFormat
import android.view.Gravity
@@ -28,6 +29,8 @@ import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import javax.inject.Inject

const val TAG = "MediaTapToTransfer"

/**
 * A controller to display and hide the Media Tap-To-Transfer chip. This chip is shown when a user
 * is currently playing media on a local "media cast sender" device (e.g. a phone) and gets close
@@ -40,14 +43,14 @@ class MediaTttChipController @Inject constructor(
    private val windowManager: WindowManager,
) {

    @SuppressLint("WrongConstant") // We're allowed to use TYPE_VOLUME_OVERLAY
    private val windowLayoutParams = WindowManager.LayoutParams().apply {
        width = WindowManager.LayoutParams.WRAP_CONTENT
        height = WindowManager.LayoutParams.WRAP_CONTENT
        gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
        type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY
        flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
        title = "Media Tap-To-Transfer Chip View"
        flags = (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
        format = PixelFormat.TRANSLUCENT
        setTrustedOverlay()
    }
@@ -76,10 +79,20 @@ class MediaTttChipController @Inject constructor(
            if (showLoading) { View.VISIBLE } else { View.GONE }

        // Undo
        val showUndo = chipState is TransferSucceeded
        currentChipView.requireViewById<View>(R.id.undo).visibility =
            if (showUndo) { View.VISIBLE } else { View.GONE }
        val undoClickListener: View.OnClickListener? =
            if (chipState is TransferSucceeded && chipState.undoRunnable != null)
                View.OnClickListener { chipState.undoRunnable.run() }
            else
                null
        val undoView = currentChipView.requireViewById<View>(R.id.undo)
        undoView.visibility = if (undoClickListener != null) {
            View.VISIBLE
        } else {
            View.GONE
        }
        undoView.setOnClickListener(undoClickListener)

        // Add view if necessary
        if (oldChipView == null) {
            windowManager.addView(chipView, windowLayoutParams)
        }
+5 −1
Original line number Diff line number Diff line
@@ -50,7 +50,11 @@ class TransferInitiated(

/**
 * A state representing that a transfer has been successfully completed.
 *
 * @property undoRunnable if present, the runnable that should be run to undo the transfer. We will
 *   show an Undo button on the chip if this runnable is present.
 */
class TransferSucceeded(
    otherDeviceName: String
    otherDeviceName: String,
    val undoRunnable: Runnable? = null
) : MediaTttChipState(R.string.media_transfer_playing, otherDeviceName)
+8 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.media.taptotransfer

import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.commandline.Command
@@ -48,7 +49,9 @@ class MediaTttCommandLineHelper @Inject constructor(
                    mediaTttChipController.displayChip(TransferInitiated(otherDeviceName))
                }
                TRANSFER_SUCCEEDED_COMMAND_NAME -> {
                    mediaTttChipController.displayChip(TransferSucceeded(otherDeviceName))
                    mediaTttChipController.displayChip(
                        TransferSucceeded(otherDeviceName, fakeUndoRunnable)
                    )
                }
                else -> {
                    pw.println("Chip type must be one of " +
@@ -75,6 +78,10 @@ class MediaTttCommandLineHelper @Inject constructor(
            pw.println("Usage: adb shell cmd statusbar $REMOVE_CHIP_COMMAND_TAG")
        }
    }

    private val fakeUndoRunnable = Runnable {
        Log.i(TAG, "Undo runnable triggered")
    }
}

@VisibleForTesting
+31 −10
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
        val chipView = getChipView()
        assertThat(chipView.getChipText()).contains(DEVICE_NAME)
        assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
        assertThat(chipView.getUndoButtonVisibility()).isEqualTo(View.GONE)
        assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
    }

    @Test
@@ -99,17 +99,39 @@ class MediaTttChipControllerTest : SysuiTestCase() {
        val chipView = getChipView()
        assertThat(chipView.getChipText()).contains(DEVICE_NAME)
        assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
        assertThat(chipView.getUndoButtonVisibility()).isEqualTo(View.GONE)
        assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
    }

    @Test
    fun transferSucceeded_chipTextContainsDeviceName_noLoadingIcon_undo() {
        mediaTttChipController.displayChip(TransferSucceeded(DEVICE_NAME))
    fun transferSucceededNullUndoRunnable_chipTextContainsDeviceName_noLoadingIcon_noUndo() {
        mediaTttChipController.displayChip(TransferSucceeded(DEVICE_NAME, undoRunnable = null))

        val chipView = getChipView()
        assertThat(chipView.getChipText()).contains(DEVICE_NAME)
        assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
        assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE)
    }

    @Test
    fun transferSucceededWithUndoRunnable_chipTextContainsDeviceName_noLoadingIcon_undoWithClick() {
        mediaTttChipController.displayChip(TransferSucceeded(DEVICE_NAME) { })

        val chipView = getChipView()
        assertThat(chipView.getChipText()).contains(DEVICE_NAME)
        assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE)
        assertThat(chipView.getUndoButtonVisibility()).isEqualTo(View.VISIBLE)
        assertThat(chipView.getUndoButton().visibility).isEqualTo(View.VISIBLE)
        assertThat(chipView.getUndoButton().hasOnClickListeners()).isTrue()
    }

    @Test
    fun transferSucceededWithUndoRunnable_undoButtonClickRunsRunnable() {
        var runnableRun = false
        val runnable = Runnable { runnableRun = true }

        mediaTttChipController.displayChip(TransferSucceeded(DEVICE_NAME, runnable))
        getChipView().getUndoButton().performClick()

        assertThat(runnableRun).isTrue()
    }

    @Test
@@ -131,9 +153,9 @@ class MediaTttChipControllerTest : SysuiTestCase() {
    @Test
    fun changeFromTransferInitiatedToTransferSucceeded_undoButtonAppears() {
        mediaTttChipController.displayChip(TransferInitiated(DEVICE_NAME))
        mediaTttChipController.displayChip(TransferSucceeded(DEVICE_NAME))
        mediaTttChipController.displayChip(TransferSucceeded(DEVICE_NAME) { })

        assertThat(getChipView().getUndoButtonVisibility()).isEqualTo(View.VISIBLE)
        assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.VISIBLE)
    }

    @Test
@@ -141,7 +163,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
        mediaTttChipController.displayChip(TransferSucceeded(DEVICE_NAME))
        mediaTttChipController.displayChip(MoveCloserToTransfer(DEVICE_NAME))

        assertThat(getChipView().getUndoButtonVisibility()).isEqualTo(View.GONE)
        assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.GONE)
    }

    private fun LinearLayout.getChipText(): String =
@@ -150,8 +172,7 @@ class MediaTttChipControllerTest : SysuiTestCase() {
    private fun LinearLayout.getLoadingIconVisibility(): Int =
        this.requireViewById<View>(R.id.loading).visibility

    private fun LinearLayout.getUndoButtonVisibility(): Int =
        this.requireViewById<View>(R.id.undo).visibility
    private fun LinearLayout.getUndoButton(): View = this.requireViewById(R.id.undo)

    private fun getChipView(): LinearLayout {
        val viewCaptor = ArgumentCaptor.forClass(View::class.java)