diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/mediattt/IDeviceSenderService.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/mediattt/IDeviceSenderService.aidl index 67259f4bb9399..eb1c9d058e208 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/mediattt/IDeviceSenderService.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/mediattt/IDeviceSenderService.aidl @@ -124,4 +124,10 @@ interface IDeviceSenderService { * on the receiver and the transfer that should've *ended* the playing on the receiver. */ oneway void transferFailed(in MediaRoute2Info mediaInfo, in DeviceInfo otherDeviceInfo); + + /** + * Invoke to notify System UI that this device is no longer close to the receiver device. + */ + oneway void noLongerCloseToReceiver( + in MediaRoute2Info mediaInfo, in DeviceInfo otherDeviceInfo); } diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java index dd60b30acad9e..4baef3aef3099 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java +++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java @@ -112,7 +112,6 @@ public interface MediaModule { MediaTttFlags mediaTttFlags, CommandRegistry commandRegistry, Context context, - MediaTttChipControllerSender mediaTttChipControllerSender, MediaTttChipControllerReceiver mediaTttChipControllerReceiver) { if (!mediaTttFlags.isMediaTttEnabled()) { return Optional.empty(); @@ -121,7 +120,6 @@ public interface MediaModule { new MediaTttCommandLineHelper( commandRegistry, context, - mediaTttChipControllerSender, mediaTttChipControllerReceiver)); } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt index da93e925ac842..37208515120a9 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt @@ -30,7 +30,6 @@ import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver -import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender import com.android.systemui.media.taptotransfer.sender.MediaTttSenderService import com.android.systemui.media.taptotransfer.sender.MoveCloserToEndCast import com.android.systemui.media.taptotransfer.sender.MoveCloserToStartCast @@ -55,7 +54,6 @@ import javax.inject.Inject class MediaTttCommandLineHelper @Inject constructor( commandRegistry: CommandRegistry, private val context: Context, - private val mediaTttChipControllerSender: MediaTttChipControllerSender, private val mediaTttChipControllerReceiver: MediaTttChipControllerReceiver, ) { private var senderService: IDeviceSenderService? = null @@ -67,17 +65,15 @@ class MediaTttCommandLineHelper @Inject constructor( } init { - commandRegistry.registerCommand( - ADD_CHIP_COMMAND_SENDER_TAG) { AddChipCommandSender() } - commandRegistry.registerCommand( - REMOVE_CHIP_COMMAND_SENDER_TAG) { RemoveChipCommandSender() } + commandRegistry.registerCommand(SENDER_COMMAND) { SenderCommand() } commandRegistry.registerCommand( ADD_CHIP_COMMAND_RECEIVER_TAG) { AddChipCommandReceiver() } commandRegistry.registerCommand( REMOVE_CHIP_COMMAND_RECEIVER_TAG) { RemoveChipCommandReceiver() } } - inner class AddChipCommandSender : Command { + /** All commands for the sender device. */ + inner class SenderCommand : Command { override fun execute(pw: PrintWriter, args: List) { val otherDeviceName = args[0] val mediaInfo = MediaRoute2Info.Builder("id", "Test Name") @@ -145,24 +141,29 @@ class MediaTttCommandLineHelper @Inject constructor( senderService.transferFailed(mediaInfo, otherDeviceInfo) } } + NO_LONGER_CLOSE_TO_RECEIVER_COMMAND_NAME -> { + runOnService { senderService -> + senderService.noLongerCloseToReceiver(mediaInfo, otherDeviceInfo) + context.unbindService(senderServiceConnection) + } + } else -> { - pw.println("Chip type must be one of " + + pw.println("Sender command must be one of " + "$MOVE_CLOSER_TO_START_CAST_COMMAND_NAME, " + "$MOVE_CLOSER_TO_END_CAST_COMMAND_NAME, " + "$TRANSFER_TO_RECEIVER_TRIGGERED_COMMAND_NAME, " + "$TRANSFER_TO_THIS_DEVICE_TRIGGERED_COMMAND_NAME, " + "$TRANSFER_TO_RECEIVER_SUCCEEDED_COMMAND_NAME, " + "$TRANSFER_TO_THIS_DEVICE_SUCCEEDED_COMMAND_NAME, " + - TRANSFER_FAILED_COMMAND_NAME + "$TRANSFER_FAILED_COMMAND_NAME, " + + NO_LONGER_CLOSE_TO_RECEIVER_COMMAND_NAME ) } } } override fun help(pw: PrintWriter) { - pw.println("Usage: adb shell cmd statusbar " + - "$ADD_CHIP_COMMAND_SENDER_TAG " - ) + pw.println("Usage: adb shell cmd statusbar $SENDER_COMMAND ") } private fun runOnService(command: SenderServiceCommand) { @@ -185,19 +186,6 @@ class MediaTttCommandLineHelper @Inject constructor( } } - /** A command to REMOVE the media ttt chip on the SENDER device. */ - inner class RemoveChipCommandSender : Command { - override fun execute(pw: PrintWriter, args: List) { - mediaTttChipControllerSender.removeChip() - if (senderService != null) { - context.unbindService(senderServiceConnection) - } - } - override fun help(pw: PrintWriter) { - pw.println("Usage: adb shell cmd statusbar $REMOVE_CHIP_COMMAND_SENDER_TAG") - } - } - /** A command to DISPLAY the media ttt chip on the RECEIVER device. */ inner class AddChipCommandReceiver : Command { override fun execute(pw: PrintWriter, args: List) { @@ -245,7 +233,7 @@ class MediaTttCommandLineHelper @Inject constructor( } @VisibleForTesting -const val ADD_CHIP_COMMAND_SENDER_TAG = "media-ttt-chip-add-sender" +const val SENDER_COMMAND = "media-ttt-chip-sender" @VisibleForTesting const val REMOVE_CHIP_COMMAND_SENDER_TAG = "media-ttt-chip-remove-sender" @VisibleForTesting @@ -268,6 +256,8 @@ 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" private const val APP_ICON_CONTENT_DESCRIPTION = "Fake media app icon" private const val TAG = "MediaTapToTransferCli" diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt index 67721a543427c..adae07b58e7c7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt @@ -81,6 +81,9 @@ abstract class MediaTttChipControllerCommon( /** Hides the chip. */ fun removeChip() { + // TODO(b/203800347): We may not want to hide the chip if we're currently in a + // TransferTriggered state: Once the user has initiated the transfer, they should be able + // to move away from the receiver device but still see the status of the transfer. if (chipView == null) { return } windowManager.removeView(chipView) chipView = null diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderService.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderService.kt index 8d9d7a9f9ce84..717752e536b0e 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderService.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderService.kt @@ -88,6 +88,13 @@ class MediaTttSenderService @Inject constructor( mediaInfo, otherDeviceInfo, undoCallback ) } + + override fun noLongerCloseToReceiver( + mediaInfo: MediaRoute2Info, + otherDeviceInfo: DeviceInfo + ) { + this@MediaTttSenderService.noLongerCloseToReceiver() + } } // TODO(b/203800643): Use the app icon from the media info instead of a fake one. @@ -168,4 +175,8 @@ class MediaTttSenderService @Inject constructor( ) controller.displayChip(chipState) } + + private fun noLongerCloseToReceiver() { + controller.removeChip() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt index 9b163058ab32f..a1ec38f630ed3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt @@ -21,7 +21,6 @@ import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver -import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender import com.android.systemui.media.taptotransfer.sender.MediaTttSenderService import com.android.systemui.shared.mediattt.DeviceInfo import com.android.systemui.shared.mediattt.IDeviceSenderService @@ -51,8 +50,6 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() { private lateinit var mediaTttCommandLineHelper: MediaTttCommandLineHelper - @Mock - private lateinit var mediaTttChipControllerSender: MediaTttChipControllerSender @Mock private lateinit var mediaTttChipControllerReceiver: MediaTttChipControllerReceiver @Mock @@ -72,27 +69,15 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() { MediaTttCommandLineHelper( commandRegistry, context, - mediaTttChipControllerSender, mediaTttChipControllerReceiver, ) } @Test(expected = IllegalStateException::class) - fun constructor_addSenderCommandAlreadyRegistered() { - // Since creating the chip controller should automatically register the add command, it + fun constructor_senderCommandAlreadyRegistered() { + // Since creating the chip controller should automatically register the sender command, it // should throw when registering it again. - commandRegistry.registerCommand( - ADD_CHIP_COMMAND_SENDER_TAG - ) { EmptyCommand() } - } - - @Test(expected = IllegalStateException::class) - fun constructor_removeSenderCommandAlreadyRegistered() { - // Since creating the chip controller should automatically register the remove command, it - // should throw when registering it again. - commandRegistry.registerCommand( - REMOVE_CHIP_COMMAND_SENDER_TAG - ) { EmptyCommand() } + commandRegistry.registerCommand(SENDER_COMMAND) { EmptyCommand() } } @Test(expected = IllegalStateException::class) @@ -187,10 +172,12 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() { } @Test - fun sender_removeCommand_chipRemoved() { - commandRegistry.onShellCommand(pw, arrayOf(REMOVE_CHIP_COMMAND_SENDER_TAG)) + fun sender_noLongerCloseToReceiver_serviceCallbackCalledAndServiceUnbound() { + commandRegistry.onShellCommand(pw, getNoLongerCloseToReceiverCommand()) - verify(mediaTttChipControllerSender).removeChip() + // Once we're no longer close to the receiver, we should unbind the service. + assertThat(context.isBound(mediaSenderServiceComponentName)).isFalse() + verify(mediaSenderService).noLongerCloseToReceiver(any(), any()) } @Test @@ -209,53 +196,60 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() { private fun getMoveCloserToStartCastCommand(): Array = arrayOf( - ADD_CHIP_COMMAND_SENDER_TAG, + SENDER_COMMAND, DEVICE_NAME, MOVE_CLOSER_TO_START_CAST_COMMAND_NAME ) private fun getMoveCloserToEndCastCommand(): Array = arrayOf( - ADD_CHIP_COMMAND_SENDER_TAG, + SENDER_COMMAND, DEVICE_NAME, MOVE_CLOSER_TO_END_CAST_COMMAND_NAME ) private fun getTransferToReceiverTriggeredCommand(): Array = arrayOf( - ADD_CHIP_COMMAND_SENDER_TAG, + SENDER_COMMAND, DEVICE_NAME, TRANSFER_TO_RECEIVER_TRIGGERED_COMMAND_NAME ) private fun getTransferToThisDeviceTriggeredCommand(): Array = arrayOf( - ADD_CHIP_COMMAND_SENDER_TAG, + SENDER_COMMAND, DEVICE_NAME, TRANSFER_TO_THIS_DEVICE_TRIGGERED_COMMAND_NAME ) private fun getTransferToReceiverSucceededCommand(): Array = arrayOf( - ADD_CHIP_COMMAND_SENDER_TAG, + SENDER_COMMAND, DEVICE_NAME, TRANSFER_TO_RECEIVER_SUCCEEDED_COMMAND_NAME ) private fun getTransferToThisDeviceSucceededCommand(): Array = arrayOf( - ADD_CHIP_COMMAND_SENDER_TAG, + SENDER_COMMAND, DEVICE_NAME, TRANSFER_TO_THIS_DEVICE_SUCCEEDED_COMMAND_NAME ) private fun getTransferFailedCommand(): Array = arrayOf( - ADD_CHIP_COMMAND_SENDER_TAG, + SENDER_COMMAND, DEVICE_NAME, TRANSFER_FAILED_COMMAND_NAME ) + private fun getNoLongerCloseToReceiverCommand(): Array = + arrayOf( + SENDER_COMMAND, + DEVICE_NAME, + NO_LONGER_CLOSE_TO_RECEIVER_COMMAND_NAME + ) + class EmptyCommand : Command { override fun execute(pw: PrintWriter, args: List) { } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderServiceTest.kt index e7304d49f2469..11b727ec507ca 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderServiceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderServiceTest.kt @@ -114,4 +114,11 @@ class MediaTttSenderServiceTest : SysuiTestCase() { verify(controller).displayChip(any()) } + + @Test + fun noLongerCloseToReceiver_controllerRemoveChipTriggered() { + service.noLongerCloseToReceiver(mediaInfo, DeviceInfo("Fake name")) + + verify(controller).removeChip() + } }