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

Commit 78ea1419 authored by Caitlin Cassidy's avatar Caitlin Cassidy Committed by Android (Google) Code Review
Browse files

Merge "[Media TTT] Refactor the command line interface into its own class and...

Merge "[Media TTT] Refactor the command line interface into its own class and use sealed classes for the chip states."
parents be3958b7 733f7fb1
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.media.taptotransfer.MediaTttChipController;
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
import com.android.systemui.people.PeopleProvider;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
@@ -133,6 +134,7 @@ public interface SysUIComponent {
        getNaturalRotationUnfoldProgressProvider().ifPresent(o -> o.init());
        // No init method needed, just needs to be gotten so that it's created.
        getMediaTttChipController();
        getMediaTttCommandLineHelper();
    }

    /**
@@ -182,6 +184,9 @@ public interface SysUIComponent {
    /** */
    Optional<MediaTttChipController> getMediaTttChipController();

    /** */
    Optional<MediaTttCommandLineHelper> getMediaTttCommandLineHelper();

    /**
     * Member injection into the supplied argument.
     */
+15 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.media.MediaHostStatesManager;
import com.android.systemui.media.taptotransfer.MediaTttChipController;
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
import com.android.systemui.media.taptotransfer.MediaTttFlags;
import com.android.systemui.statusbar.commandline.CommandRegistry;

@@ -78,11 +79,23 @@ public interface MediaModule {
    static Optional<MediaTttChipController> providesMediaTttChipController(
            MediaTttFlags mediaTttFlags,
            Context context,
            CommandRegistry commandRegistry,
            WindowManager windowManager) {
        if (!mediaTttFlags.isMediaTttEnabled()) {
            return Optional.empty();
        }
        return Optional.of(new MediaTttChipController(commandRegistry, context, windowManager));
        return Optional.of(new MediaTttChipController(context, windowManager));
    }

    /** */
    @Provides
    @SysUISingleton
    static Optional<MediaTttCommandLineHelper> providesMediaTttCommandLineHelper(
            MediaTttFlags mediaTttFlags,
            CommandRegistry commandRegistry,
            MediaTttChipController mediaTttChipController) {
        if (!mediaTttFlags.isMediaTttEnabled()) {
            return Optional.empty();
        }
        return Optional.of(new MediaTttCommandLineHelper(commandRegistry, mediaTttChipController));
    }
}
+7 −59
Original line number Diff line number Diff line
@@ -24,13 +24,8 @@ import android.view.View
import android.view.WindowManager
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.annotation.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import java.io.PrintWriter
import javax.inject.Inject

/**
@@ -41,14 +36,9 @@ import javax.inject.Inject
 */
@SysUISingleton
class MediaTttChipController @Inject constructor(
    commandRegistry: CommandRegistry,
    private val context: Context,
    private val windowManager: WindowManager,
) {
    init {
        commandRegistry.registerCommand(ADD_CHIP_COMMAND_TAG) { AddChipCommand() }
        commandRegistry.registerCommand(REMOVE_CHIP_COMMAND_TAG) { RemoveChipCommand() }
    }

    private val windowLayoutParams = WindowManager.LayoutParams().apply {
        width = WindowManager.LayoutParams.WRAP_CONTENT
@@ -65,7 +55,8 @@ class MediaTttChipController @Inject constructor(
    /** The chip view currently being displayed. Null if the chip is not being displayed. */
    private var chipView: LinearLayout? = null

    private fun displayChip(chipType: ChipType, otherDeviceName: String) {
    /** Displays the chip view for the given state. */
    fun displayChip(chipState: MediaTttChipState) {
        val oldChipView = chipView
        if (chipView == null) {
            chipView = LayoutInflater
@@ -76,16 +67,16 @@ class MediaTttChipController @Inject constructor(

        // Text
        currentChipView.requireViewById<TextView>(R.id.text).apply {
            text = context.getString(chipType.chipText, otherDeviceName)
            text = context.getString(chipState.chipText, chipState.otherDeviceName)
        }

        // Loading
        val showLoading = chipType == ChipType.TRANSFER_INITIATED
        val showLoading = chipState is TransferInitiated
        currentChipView.requireViewById<View>(R.id.loading).visibility =
            if (showLoading) { View.VISIBLE } else { View.GONE }

        // Undo
        val showUndo = chipType == ChipType.TRANSFER_SUCCEEDED
        val showUndo = chipState is TransferSucceeded
        currentChipView.requireViewById<View>(R.id.undo).visibility =
            if (showUndo) { View.VISIBLE } else { View.GONE }

@@ -94,53 +85,10 @@ class MediaTttChipController @Inject constructor(
        }
    }

    private fun removeChip() {
    /** Hides the chip. */
    fun removeChip() {
        if (chipView == null) { return }
        windowManager.removeView(chipView)
        chipView = null
    }

    @VisibleForTesting
    enum class ChipType(
        @StringRes internal val chipText: Int
    ) {
        MOVE_CLOSER_TO_TRANSFER(R.string.media_move_closer_to_transfer),
        TRANSFER_INITIATED(R.string.media_transfer_playing),
        TRANSFER_SUCCEEDED(R.string.media_transfer_playing),
    }

    inner class AddChipCommand : Command {
        override fun execute(pw: PrintWriter, args: List<String>) {
            val chipTypeArg = args[1]
            ChipType.values().forEach {
                if (it.name == chipTypeArg) {
                    displayChip(it, otherDeviceName = args[0])
                    return
                }
            }

            pw.println("Chip type must be one of " +
                    ChipType.values().map { it.name }.reduce { acc, s -> "$acc, $s" })
        }

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

    inner class RemoveChipCommand : Command {
        override fun execute(pw: PrintWriter, args: List<String>) = removeChip()
        override fun help(pw: PrintWriter) {
            pw.println("Usage: adb shell cmd statusbar $REMOVE_CHIP_COMMAND_TAG")
        }
    }

    companion object {
        @VisibleForTesting
        const val ADD_CHIP_COMMAND_TAG = "media-ttt-chip-add"
        @VisibleForTesting
        const val REMOVE_CHIP_COMMAND_TAG = "media-ttt-chip-remove"
    }
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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

import androidx.annotation.StringRes
import com.android.systemui.R

/**
 * A class that stores all the information necessary to display the media tap-to-transfer chip in
 * certain states.
 *
 * This is a sealed class where each subclass represents a specific chip state. Each subclass can
 * contain additional information that is necessary for only that state.
 */
sealed class MediaTttChipState(
    /** A string resource for the text that the chip should display. */
    @StringRes internal val chipText: Int,
    /** The name of the other device involved in the transfer. */
    internal val otherDeviceName: String
)

/**
 * A state representing that the two devices are close but not close enough to initiate a transfer.
 * The chip will instruct the user to move closer in order to initiate the transfer.
 */
class MoveCloserToTransfer(
    otherDeviceName: String
) : MediaTttChipState(R.string.media_move_closer_to_transfer, otherDeviceName)

/**
 * A state representing that a transfer has been initiated (but not completed).
 */
class TransferInitiated(
    otherDeviceName: String
) : MediaTttChipState(R.string.media_transfer_playing, otherDeviceName)

/**
 * A state representing that a transfer has been successfully completed.
 */
class TransferSucceeded(
    otherDeviceName: String
) : MediaTttChipState(R.string.media_transfer_playing, otherDeviceName)
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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

import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import java.io.PrintWriter
import javax.inject.Inject

/**
 * A helper class to test the media tap-to-transfer chip via the command line. See inner classes for
 * command usages.
 */
@SysUISingleton
class MediaTttCommandLineHelper @Inject constructor(
    commandRegistry: CommandRegistry,
    private val mediaTttChipController: MediaTttChipController
) {
    init {
        commandRegistry.registerCommand(ADD_CHIP_COMMAND_TAG) { AddChipCommand() }
        commandRegistry.registerCommand(REMOVE_CHIP_COMMAND_TAG) { RemoveChipCommand() }
    }

    inner class AddChipCommand : Command {
        override fun execute(pw: PrintWriter, args: List<String>) {
            val otherDeviceName = args[0]
            when (args[1]) {
                MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME -> {
                    mediaTttChipController.displayChip(MoveCloserToTransfer(otherDeviceName))
                }
                TRANSFER_INITIATED_COMMAND_NAME -> {
                    mediaTttChipController.displayChip(TransferInitiated(otherDeviceName))
                }
                TRANSFER_SUCCEEDED_COMMAND_NAME -> {
                    mediaTttChipController.displayChip(TransferSucceeded(otherDeviceName))
                }
                else -> {
                    pw.println("Chip type must be one of " +
                            "$MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME, " +
                            "$TRANSFER_INITIATED_COMMAND_NAME, " +
                            TRANSFER_SUCCEEDED_COMMAND_NAME
                    )
                }
            }
        }

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

    inner class RemoveChipCommand : Command {
        override fun execute(pw: PrintWriter, args: List<String>) {
            mediaTttChipController.removeChip()
        }
        override fun help(pw: PrintWriter) {
            pw.println("Usage: adb shell cmd statusbar $REMOVE_CHIP_COMMAND_TAG")
        }
    }
}

@VisibleForTesting
const val ADD_CHIP_COMMAND_TAG = "media-ttt-chip-add"
@VisibleForTesting
const val REMOVE_CHIP_COMMAND_TAG = "media-ttt-chip-remove"
@VisibleForTesting
val MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME = MoveCloserToTransfer::class.simpleName!!
@VisibleForTesting
val TRANSFER_INITIATED_COMMAND_NAME = TransferInitiated::class.simpleName!!
@VisibleForTesting
val TRANSFER_SUCCEEDED_COMMAND_NAME = TransferSucceeded::class.simpleName!!
Loading