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

Commit 623a9ccf authored by Caitlin Cassidy's avatar Caitlin Cassidy
Browse files

[Media TTT] Update the sender view controller and the command line helper to

handle the sender @SystemApi states.

Bug: 216318437
Test: media.taptotransfer tests (still ignored because they were failing
on some cuttlefish builds, but they do pass locally)
Test: all adb commands work as expected (e.g. `adb shell cmd statusbar
media-ttt-chip-sender MyTablet TransferToThisDeviceSucceeded` shows the
succeeded chip)

Change-Id: Ic3fb31854bb1327b698a1a432dc8cad7513dfe35
parent 44386a5a
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.view.WindowManager;

import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
@@ -35,6 +36,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.commandline.CommandRegistry;

import java.util.Optional;
import java.util.concurrent.Executor;

import javax.inject.Named;

@@ -99,13 +101,13 @@ public interface MediaModule {
    @SysUISingleton
    static Optional<MediaTttChipControllerSender> providesMediaTttChipControllerSender(
            MediaTttFlags mediaTttFlags,
            CommandQueue commandQueue,
            Context context,
            WindowManager windowManager,
            CommandQueue commandQueue) {
            WindowManager windowManager) {
        if (!mediaTttFlags.isMediaTttEnabled()) {
            return Optional.empty();
        }
        return Optional.of(new MediaTttChipControllerSender(context, windowManager, commandQueue));
        return Optional.of(new MediaTttChipControllerSender(commandQueue, context, windowManager));
    }

    /** */
@@ -128,6 +130,7 @@ public interface MediaModule {
            MediaTttFlags mediaTttFlags,
            CommandRegistry commandRegistry,
            Context context,
            @Main Executor mainExecutor,
            MediaTttChipControllerReceiver mediaTttChipControllerReceiver) {
        if (!mediaTttFlags.isMediaTttEnabled()) {
            return Optional.empty();
@@ -136,6 +139,7 @@ public interface MediaModule {
                new MediaTttCommandLineHelper(
                        commandRegistry,
                        context,
                        mainExecutor,
                        mediaTttChipControllerReceiver));
    }

+77 −28
Original line number Diff line number Diff line
@@ -21,13 +21,15 @@ import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Icon
import android.media.MediaRoute2Info
import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver
import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver
import com.android.systemui.media.taptotransfer.sender.MoveCloserToEndCast
import com.android.systemui.media.taptotransfer.sender.MoveCloserToStartCast
import com.android.systemui.media.taptotransfer.sender.AlmostCloseToEndCast
import com.android.systemui.media.taptotransfer.sender.AlmostCloseToStartCast
import com.android.systemui.media.taptotransfer.sender.TransferFailed
import com.android.systemui.media.taptotransfer.sender.TransferToReceiverTriggered
import com.android.systemui.media.taptotransfer.sender.TransferToThisDeviceSucceeded
@@ -36,6 +38,7 @@ import com.android.systemui.media.taptotransfer.sender.TransferToReceiverSucceed
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject

/**
@@ -46,6 +49,7 @@ import javax.inject.Inject
class MediaTttCommandLineHelper @Inject constructor(
    commandRegistry: CommandRegistry,
    private val context: Context,
    @Main private val mainExecutor: Executor,
    private val mediaTttChipControllerReceiver: MediaTttChipControllerReceiver,
) {
    private val appIconDrawable =
@@ -53,6 +57,28 @@ class MediaTttCommandLineHelper @Inject constructor(
            it.setTint(Color.YELLOW)
        }

    /**
     * A map from a display state string typed in the command line to the display int it represents.
     */
    private val stateStringToStateInt: Map<String, Int> = mapOf(
        AlmostCloseToStartCast::class.simpleName!!
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
        AlmostCloseToEndCast::class.simpleName!!
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST,
        TransferToReceiverTriggered::class.simpleName!!
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED,
        TransferToThisDeviceTriggered::class.simpleName!!
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED,
        TransferToReceiverSucceeded::class.simpleName!!
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED,
        TransferToThisDeviceSucceeded::class.simpleName!!
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED,
        TransferFailed::class.simpleName!!
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
        FAR_FROM_RECEIVER_STATE
                to StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER
    )

    init {
        commandRegistry.registerCommand(SENDER_COMMAND) { SenderCommand() }
        commandRegistry.registerCommand(
@@ -68,22 +94,59 @@ class MediaTttCommandLineHelper @Inject constructor(
                    .addFeature("feature")
                    .build()

            @StatusBarManager.MediaTransferSenderState
            val displayState = stateStringToStateInt[args[1]]
            if (displayState == null) {
                pw.println("Invalid command name")
                return
            }

            val statusBarManager = context.getSystemService(Context.STATUS_BAR_SERVICE)
                    as StatusBarManager
            statusBarManager.updateMediaTapToTransferSenderDisplay(
                    StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
                    displayState,
                    routeInfo,
                    /* undoExecutor= */ null,
                    /* undoCallback= */ null
                getUndoExecutor(displayState),
                getUndoCallback(displayState)
            )
            // TODO(b/216318437): Migrate the rest of the callbacks to StatusBarManager.
        }

        private fun getUndoExecutor(
            @StatusBarManager.MediaTransferSenderState displayState: Int
        ): Executor? {
            return if (isSucceededState(displayState)) {
                mainExecutor
            } else {
                null
            }
        }

        private fun getUndoCallback(
            @StatusBarManager.MediaTransferSenderState displayState: Int
        ): Runnable? {
            return if (isSucceededState(displayState)) {
                Runnable { Log.i(CLI_TAG, "Undo triggered for $displayState") }
            } else {
                null
            }
        }

        private fun isSucceededState(
            @StatusBarManager.MediaTransferSenderState displayState: Int
        ): Boolean {
            return displayState ==
                    StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED ||
                    displayState ==
                    StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED
        }

        override fun help(pw: PrintWriter) {
            pw.println("Usage: adb shell cmd statusbar $SENDER_COMMAND <deviceName> <chipStatus>")
            pw.println("Usage: adb shell cmd statusbar $SENDER_COMMAND <deviceName> <chipState>")
        }
    }

    // TODO(b/216318437): Migrate the receiver callbacks to StatusBarManager.

    /** A command to DISPLAY the media ttt chip on the RECEIVER device. */
    inner class AddChipCommandReceiver : Command {
        override fun execute(pw: PrintWriter, args: List<String>) {
@@ -110,29 +173,15 @@ class MediaTttCommandLineHelper @Inject constructor(
@VisibleForTesting
const val SENDER_COMMAND = "media-ttt-chip-sender"
@VisibleForTesting
const val REMOVE_CHIP_COMMAND_SENDER_TAG = "media-ttt-chip-remove-sender"
@VisibleForTesting
const val ADD_CHIP_COMMAND_RECEIVER_TAG = "media-ttt-chip-add-receiver"
@VisibleForTesting
const val REMOVE_CHIP_COMMAND_RECEIVER_TAG = "media-ttt-chip-remove-receiver"
@VisibleForTesting
val MOVE_CLOSER_TO_START_CAST_COMMAND_NAME = MoveCloserToStartCast::class.simpleName!!
@VisibleForTesting
val MOVE_CLOSER_TO_END_CAST_COMMAND_NAME = MoveCloserToEndCast::class.simpleName!!
@VisibleForTesting
val TRANSFER_TO_RECEIVER_TRIGGERED_COMMAND_NAME = TransferToReceiverTriggered::class.simpleName!!
@VisibleForTesting
val TRANSFER_TO_THIS_DEVICE_TRIGGERED_COMMAND_NAME =
    TransferToThisDeviceTriggered::class.simpleName!!
@VisibleForTesting
val TRANSFER_TO_RECEIVER_SUCCEEDED_COMMAND_NAME = TransferToReceiverSucceeded::class.simpleName!!
@VisibleForTesting
val TRANSFER_TO_THIS_DEVICE_SUCCEEDED_COMMAND_NAME =
    TransferToThisDeviceSucceeded::class.simpleName!!
@VisibleForTesting
val TRANSFER_FAILED_COMMAND_NAME = TransferFailed::class.simpleName!!
@VisibleForTesting
val NO_LONGER_CLOSE_TO_RECEIVER_COMMAND_NAME = "NoLongerCloseToReceiver"
val FAR_FROM_RECEIVER_STATE = "FarFromReceiver"

private const val APP_ICON_CONTENT_DESCRIPTION = "Fake media app icon"
private const val TAG = "MediaTapToTransferCli"
private const val CLI_TAG = "MediaTransferCli"

private val routeInfo = MediaRoute2Info.Builder("id", "Test Name")
    .addFeature("feature")
    .build()
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ sealed class ChipStateSender(
 *
 * @property otherDeviceName the name of the other device involved in the transfer.
 */
class MoveCloserToStartCast(
class AlmostCloseToStartCast(
    appIconDrawable: Drawable,
    appIconContentDescription: String,
    private val otherDeviceName: String,
@@ -76,7 +76,7 @@ class MoveCloserToStartCast(
 *
 * @property otherDeviceName the name of the other device involved in the transfer.
 */
class MoveCloserToEndCast(
class AlmostCloseToEndCast(
    appIconDrawable: Drawable,
    appIconContentDescription: String,
    private val otherDeviceName: String,
+68 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Icon
import android.media.MediaRoute2Info
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
@@ -38,9 +39,9 @@ import javax.inject.Inject
 */
@SysUISingleton
class MediaTttChipControllerSender @Inject constructor(
    commandQueue: CommandQueue,
    context: Context,
    windowManager: WindowManager,
    private val commandQueue: CommandQueue
) : MediaTttChipControllerCommon<ChipStateSender>(
    context, windowManager, R.layout.media_ttt_chip
) {
@@ -50,25 +51,80 @@ class MediaTttChipControllerSender @Inject constructor(
            it.setTint(Color.YELLOW)
        }

    private val commandQueueCallback = object : CommandQueue.Callbacks {
    private val commandQueueCallbacks = object : CommandQueue.Callbacks {
        override fun updateMediaTapToTransferSenderDisplay(
                @StatusBarManager.MediaTransferSenderState displayState: Int,
                routeInfo: MediaRoute2Info,
                undoCallback: IUndoMediaTransferCallback?
        ) {
            // TODO(b/216318437): Trigger displayChip with the right state based on displayState.
            displayChip(
                MoveCloserToStartCast(
            this@MediaTttChipControllerSender.updateMediaTapToTransferSenderDisplay(
                displayState, routeInfo, undoCallback
            )
        }
    }

    init {
        commandQueue.addCallback(commandQueueCallbacks)
    }

    private fun updateMediaTapToTransferSenderDisplay(
        @StatusBarManager.MediaTransferSenderState displayState: Int,
        routeInfo: MediaRoute2Info,
        undoCallback: IUndoMediaTransferCallback?
    ) {
        // TODO(b/217418566): This app icon content description is incorrect --
        //   routeInfo.name is the name of the device, not the name of the app.
                    fakeAppIconDrawable, routeInfo.name.toString(), routeInfo.name.toString()
        val appIconContentDescription = routeInfo.name.toString()
        val otherDeviceName = routeInfo.name.toString()
        val chipState = when(displayState) {
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST ->
                AlmostCloseToStartCast(
                    fakeAppIconDrawable, appIconContentDescription, otherDeviceName
                )
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST ->
                AlmostCloseToEndCast(
                    fakeAppIconDrawable, appIconContentDescription, otherDeviceName
                )
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED ->
                TransferToReceiverTriggered(
                    fakeAppIconDrawable, appIconContentDescription, otherDeviceName
                )
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED ->
                TransferToThisDeviceTriggered(
                    fakeAppIconDrawable, appIconContentDescription
                )
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED ->
                TransferToReceiverSucceeded(
                    fakeAppIconDrawable,
                    appIconContentDescription,
                    otherDeviceName,
                    undoCallback
                )
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED ->
                TransferToThisDeviceSucceeded(
                    fakeAppIconDrawable,
                    appIconContentDescription,
                    otherDeviceName,
                    undoCallback
                )
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED,
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED ->
                TransferFailed(
                    fakeAppIconDrawable, appIconContentDescription
                )
            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER -> {
                removeChip()
                null
            }
            else -> {
                Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState")
                null
            }
        }

    init {
        commandQueue.addCallback(commandQueueCallback)
        chipState?.let {
            displayChip(it)
        }
    }

    /** Displays the chip view for the given state. */
@@ -97,3 +153,5 @@ class MediaTttChipControllerSender @Inject constructor(
            if (showFailure) { View.VISIBLE } else { View.GONE }
    }
}

const val SENDER_TAG = "MediaTapToTransferSender"
+94 −107

File changed.

Preview size limit exceeded, changes collapsed.

Loading