Merge "[Media TTT] Add the aidl interface for the sender and a service that implements it."
This commit is contained in:
committed by
Android (Google) Code Review
commit
71abd1233b
@@ -855,6 +855,12 @@
|
||||
android:singleUser="true"
|
||||
android:permission="android.permission.BIND_DREAM_SERVICE" />
|
||||
|
||||
<!-- Service for external clients to do media transfer -->
|
||||
<!-- TODO(b/203800643): Export and guard with a permission. -->
|
||||
<service
|
||||
android:name=".media.taptotransfer.sender.MediaTttSenderService"
|
||||
/>
|
||||
|
||||
<receiver
|
||||
android:name=".tuner.TunerService$ClearReceiver"
|
||||
android:exported="false">
|
||||
|
||||
@@ -2152,8 +2152,8 @@
|
||||
<!--- ****** Media tap-to-transfer ****** -->
|
||||
<!-- Text for a button to undo the media transfer. [CHAR LIMIT=20] -->
|
||||
<string name="media_transfer_undo">Undo</string>
|
||||
<!-- Text to ask the user to move their device closer to a different device (deviceName) in order to play music on the different device. [CHAR LIMIT=75] -->
|
||||
<string name="media_move_closer_to_transfer">Move closer to play on <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g></string>
|
||||
<!-- Text to ask the user to move their device closer to a different device (deviceName) in order to play media on the different device. [CHAR LIMIT=75] -->
|
||||
<string name="media_move_closer_to_start_cast">Move closer to play on <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g></string>
|
||||
<!-- Text informing the user that their media is now playing on a different device (deviceName). [CHAR LIMIT=50] -->
|
||||
<string name="media_transfer_playing">Playing on <xliff:g id="deviceName" example="My Tablet">%1$s</xliff:g></string>
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.shared.mediattt;
|
||||
|
||||
import android.media.MediaRoute2Info;
|
||||
|
||||
/**
|
||||
* A callback interface that can be invoked to trigger media transfer events on System UI.
|
||||
*
|
||||
* This interface is for the *sender* device, which is the device currently playing media. This
|
||||
* sender device can transfer the media to a different device, called the receiver.
|
||||
*
|
||||
* System UI will implement this interface and other services will invoke it.
|
||||
*/
|
||||
interface IDeviceSenderCallback {
|
||||
/**
|
||||
* Invoke to notify System UI that this device (the sender) is close to a receiver device, so
|
||||
* the user can potentially *start* a cast to the receiver device if the user moves their device
|
||||
* a bit closer.
|
||||
*
|
||||
* Important notes:
|
||||
* - When this callback triggers, the device is close enough to inform the user that
|
||||
* transferring is an option, but the device is *not* close enough to actually initiate a
|
||||
* transfer yet.
|
||||
* - This callback is for *starting* a cast. It should be used when this device is currently
|
||||
* playing media locally and the media should be transferred to be played on the receiver
|
||||
* device instead.
|
||||
*/
|
||||
// TODO(b/203800643): Add the otherDeviceInfo parameter.
|
||||
oneway void closeToReceiverToStartCast(in MediaRoute2Info mediaInfo);
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.media.dagger;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.view.WindowManager;
|
||||
|
||||
@@ -30,6 +31,7 @@ import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
|
||||
import com.android.systemui.media.taptotransfer.MediaTttFlags;
|
||||
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.statusbar.commandline.CommandRegistry;
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor;
|
||||
|
||||
@@ -38,8 +40,11 @@ import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.ClassKey;
|
||||
import dagger.multibindings.IntoMap;
|
||||
|
||||
/** Dagger module for the media package. */
|
||||
@Module
|
||||
@@ -128,4 +133,10 @@ public interface MediaModule {
|
||||
mediaTttChipControllerReceiver,
|
||||
mainExecutor));
|
||||
}
|
||||
|
||||
/** Inject into MediaTttSenderService. */
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(MediaTttSenderService.class)
|
||||
Service bindMediaTttSenderService(MediaTttSenderService service);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,14 @@
|
||||
|
||||
package com.android.systemui.media.taptotransfer
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Icon
|
||||
import android.media.MediaRoute2Info
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.systemui.R
|
||||
@@ -27,9 +32,11 @@ 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.MediaTttChipControllerSender
|
||||
import com.android.systemui.media.taptotransfer.sender.MoveCloserToTransfer
|
||||
import com.android.systemui.media.taptotransfer.sender.MediaTttSenderService
|
||||
import com.android.systemui.media.taptotransfer.sender.MoveCloserToStartCast
|
||||
import com.android.systemui.media.taptotransfer.sender.TransferInitiated
|
||||
import com.android.systemui.media.taptotransfer.sender.TransferSucceeded
|
||||
import com.android.systemui.shared.mediattt.IDeviceSenderCallback
|
||||
import com.android.systemui.statusbar.commandline.Command
|
||||
import com.android.systemui.statusbar.commandline.CommandRegistry
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
@@ -44,11 +51,14 @@ import javax.inject.Inject
|
||||
@SysUISingleton
|
||||
class MediaTttCommandLineHelper @Inject constructor(
|
||||
commandRegistry: CommandRegistry,
|
||||
context: Context,
|
||||
private val context: Context,
|
||||
private val mediaTttChipControllerSender: MediaTttChipControllerSender,
|
||||
private val mediaTttChipControllerReceiver: MediaTttChipControllerReceiver,
|
||||
@Main private val mainExecutor: DelayableExecutor,
|
||||
) {
|
||||
private var senderCallback: IDeviceSenderCallback? = null
|
||||
private val senderServiceConnection = SenderServiceConnection()
|
||||
|
||||
private val appIconDrawable =
|
||||
Icon.createWithResource(context, R.drawable.ic_avatar_user).loadDrawable(context).also {
|
||||
it.setTint(Color.YELLOW)
|
||||
@@ -68,14 +78,19 @@ class MediaTttCommandLineHelper @Inject constructor(
|
||||
inner class AddChipCommandSender : Command {
|
||||
override fun execute(pw: PrintWriter, args: List<String>) {
|
||||
val otherDeviceName = args[0]
|
||||
val mediaInfo = MediaRoute2Info.Builder("id", "Test Name")
|
||||
.addFeature("feature")
|
||||
.build()
|
||||
|
||||
when (args[1]) {
|
||||
MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME -> {
|
||||
mediaTttChipControllerSender.displayChip(
|
||||
MoveCloserToTransfer(
|
||||
appIconDrawable, APP_ICON_CONTENT_DESCRIPTION, otherDeviceName
|
||||
)
|
||||
)
|
||||
MOVE_CLOSER_TO_START_CAST_COMMAND_NAME -> {
|
||||
runOnService { senderCallback ->
|
||||
senderCallback.closeToReceiverToStartCast(mediaInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/203800643): Migrate other commands to invoke the service instead of the
|
||||
// controller.
|
||||
TRANSFER_INITIATED_COMMAND_NAME -> {
|
||||
val futureTask = FutureTask { fakeUndoRunnable }
|
||||
mediaTttChipControllerSender.displayChip(
|
||||
@@ -101,7 +116,7 @@ class MediaTttCommandLineHelper @Inject constructor(
|
||||
}
|
||||
else -> {
|
||||
pw.println("Chip type must be one of " +
|
||||
"$MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME, " +
|
||||
"$MOVE_CLOSER_TO_START_CAST_COMMAND_NAME, " +
|
||||
"$TRANSFER_INITIATED_COMMAND_NAME, " +
|
||||
TRANSFER_SUCCEEDED_COMMAND_NAME
|
||||
)
|
||||
@@ -114,19 +129,40 @@ class MediaTttCommandLineHelper @Inject constructor(
|
||||
"$ADD_CHIP_COMMAND_SENDER_TAG <deviceName> <chipStatus>"
|
||||
)
|
||||
}
|
||||
|
||||
private fun runOnService(command: SenderCallbackCommand) {
|
||||
val currentServiceCallback = senderCallback
|
||||
if (currentServiceCallback != null) {
|
||||
command.run(currentServiceCallback)
|
||||
} else {
|
||||
bindService(command)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindService(command: SenderCallbackCommand) {
|
||||
senderServiceConnection.pendingCommand = command
|
||||
val binding = context.bindService(
|
||||
Intent(context, MediaTttSenderService::class.java),
|
||||
senderServiceConnection,
|
||||
Context.BIND_AUTO_CREATE
|
||||
)
|
||||
Log.i(TAG, "Starting service binding? $binding")
|
||||
}
|
||||
}
|
||||
|
||||
/** A command to REMOVE the media ttt chip on the SENDER device. */
|
||||
inner class RemoveChipCommandSender : Command {
|
||||
override fun execute(pw: PrintWriter, args: List<String>) {
|
||||
mediaTttChipControllerSender.removeChip()
|
||||
if (senderCallback != 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<String>) {
|
||||
@@ -149,6 +185,29 @@ class MediaTttCommandLineHelper @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/** A service connection for [IDeviceSenderCallback]. */
|
||||
private inner class SenderServiceConnection : ServiceConnection {
|
||||
// A command that should be run when the service gets connected.
|
||||
var pendingCommand: SenderCallbackCommand? = null
|
||||
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
val newCallback = IDeviceSenderCallback.Stub.asInterface(service)
|
||||
senderCallback = newCallback
|
||||
pendingCommand?.run(newCallback)
|
||||
pendingCommand = null
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(className: ComponentName) {
|
||||
senderCallback = null
|
||||
}
|
||||
}
|
||||
|
||||
/** An interface defining a command that should be run on the sender callback. */
|
||||
private fun interface SenderCallbackCommand {
|
||||
/** Runs the command on the provided [senderCallback]. */
|
||||
fun run(senderCallback: IDeviceSenderCallback)
|
||||
}
|
||||
|
||||
private val fakeUndoRunnable = Runnable {
|
||||
Log.i(TAG, "Undo runnable triggered")
|
||||
}
|
||||
@@ -163,7 +222,7 @@ 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_TRANSFER_COMMAND_NAME = MoveCloserToTransfer::class.simpleName!!
|
||||
val MOVE_CLOSER_TO_START_CAST_COMMAND_NAME = MoveCloserToStartCast::class.simpleName!!
|
||||
@VisibleForTesting
|
||||
val TRANSFER_INITIATED_COMMAND_NAME = TransferInitiated::class.simpleName!!
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -40,17 +40,18 @@ sealed class ChipStateSender(
|
||||
) : MediaTttChipState(appIconDrawable, appIconContentDescription)
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* A state representing that the two devices are close but not close enough to *start* a cast to
|
||||
* the receiver device. The chip will instruct the user to move closer in order to initiate the
|
||||
* transfer to the receiver.
|
||||
*/
|
||||
class MoveCloserToTransfer(
|
||||
class MoveCloserToStartCast(
|
||||
appIconDrawable: Drawable,
|
||||
appIconContentDescription: String,
|
||||
otherDeviceName: String,
|
||||
) : ChipStateSender(
|
||||
appIconDrawable,
|
||||
appIconContentDescription,
|
||||
R.string.media_move_closer_to_transfer,
|
||||
R.string.media_move_closer_to_start_cast,
|
||||
otherDeviceName
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Icon
|
||||
import android.media.MediaRoute2Info
|
||||
import android.os.IBinder
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.shared.mediattt.IDeviceSenderCallback
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Service that allows external handlers to trigger the media chip on the sender device.
|
||||
*/
|
||||
class MediaTttSenderService @Inject constructor(
|
||||
context: Context,
|
||||
val controller: MediaTttChipControllerSender
|
||||
) : Service() {
|
||||
|
||||
// TODO(b/203800643): Add logging when callbacks trigger.
|
||||
private val binder: IBinder = object : IDeviceSenderCallback.Stub() {
|
||||
override fun closeToReceiverToStartCast(mediaInfo: MediaRoute2Info) {
|
||||
this@MediaTttSenderService.closeToReceiverToStartCast(mediaInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/203800643): Use the app icon from the media info instead of a fake one.
|
||||
private val fakeAppIconDrawable =
|
||||
Icon.createWithResource(context, R.drawable.ic_avatar_user).loadDrawable(context).also {
|
||||
it.setTint(Color.YELLOW)
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder = binder
|
||||
|
||||
private fun closeToReceiverToStartCast(mediaInfo: MediaRoute2Info) {
|
||||
val chipState = MoveCloserToStartCast(
|
||||
appIconDrawable = fakeAppIconDrawable,
|
||||
appIconContentDescription = mediaInfo.name.toString(),
|
||||
otherDeviceName = FAKE_DEVICE_NAME
|
||||
)
|
||||
controller.displayChip(chipState)
|
||||
}
|
||||
}
|
||||
|
||||
private const val FAKE_DEVICE_NAME = "Fake Other Device Name"
|
||||
@@ -16,23 +16,28 @@
|
||||
|
||||
package com.android.systemui.media.taptotransfer
|
||||
|
||||
import android.content.ComponentName
|
||||
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.MoveCloserToTransfer
|
||||
import com.android.systemui.media.taptotransfer.sender.MediaTttSenderService
|
||||
import com.android.systemui.media.taptotransfer.sender.TransferInitiated
|
||||
import com.android.systemui.media.taptotransfer.sender.TransferSucceeded
|
||||
import com.android.systemui.shared.mediattt.IDeviceSenderCallback
|
||||
import com.android.systemui.statusbar.commandline.Command
|
||||
import com.android.systemui.statusbar.commandline.CommandRegistry
|
||||
import com.android.systemui.util.concurrency.FakeExecutor
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.anyString
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
@@ -51,10 +56,19 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
|
||||
private lateinit var mediaTttChipControllerSender: MediaTttChipControllerSender
|
||||
@Mock
|
||||
private lateinit var mediaTttChipControllerReceiver: MediaTttChipControllerReceiver
|
||||
@Mock
|
||||
private lateinit var mediaSenderService: IDeviceSenderCallback.Stub
|
||||
private lateinit var mediaSenderServiceComponentName: ComponentName
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
mediaSenderServiceComponentName = ComponentName(context, MediaTttSenderService::class.java)
|
||||
context.addMockService(mediaSenderServiceComponentName, mediaSenderService)
|
||||
whenever(mediaSenderService.queryLocalInterface(anyString())).thenReturn(mediaSenderService)
|
||||
whenever(mediaSenderService.asBinder()).thenReturn(mediaSenderService)
|
||||
|
||||
mediaTttCommandLineHelper =
|
||||
MediaTttCommandLineHelper(
|
||||
commandRegistry,
|
||||
@@ -102,10 +116,11 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sender_moveCloserToTransfer_chipDisplayWithCorrectState() {
|
||||
commandRegistry.onShellCommand(pw, getMoveCloserToTransferCommand())
|
||||
fun sender_moveCloserToStartCast_serviceCallbackCalled() {
|
||||
commandRegistry.onShellCommand(pw, getMoveCloserToStartCastCommand())
|
||||
|
||||
verify(mediaTttChipControllerSender).displayChip(any(MoveCloserToTransfer::class.java))
|
||||
assertThat(context.isBound(mediaSenderServiceComponentName)).isTrue()
|
||||
verify(mediaSenderService).closeToReceiverToStartCast(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,11 +158,11 @@ class MediaTttCommandLineHelperTest : SysuiTestCase() {
|
||||
verify(mediaTttChipControllerReceiver).removeChip()
|
||||
}
|
||||
|
||||
private fun getMoveCloserToTransferCommand(): Array<String> =
|
||||
private fun getMoveCloserToStartCastCommand(): Array<String> =
|
||||
arrayOf(
|
||||
ADD_CHIP_COMMAND_SENDER_TAG,
|
||||
DEVICE_NAME,
|
||||
MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME
|
||||
MOVE_CLOSER_TO_START_CAST_COMMAND_NAME
|
||||
)
|
||||
|
||||
private fun getTransferInitiatedCommand(): Array<String> =
|
||||
|
||||
@@ -66,8 +66,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun moveCloserToTransfer_appIcon_chipTextContainsDeviceName_noLoadingIcon_noUndo() {
|
||||
controllerSender.displayChip(moveCloserToTransfer())
|
||||
fun moveCloserToStartCast_appIcon_chipTextContainsDeviceName_noLoadingIcon_noUndo() {
|
||||
controllerSender.displayChip(moveCloserToStartCast())
|
||||
|
||||
val chipView = getChipView()
|
||||
assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconDrawable)
|
||||
@@ -192,8 +192,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeFromCloserToTransferToTransferInitiated_loadingIconAppears() {
|
||||
controllerSender.displayChip(moveCloserToTransfer())
|
||||
fun changeFromCloserToStartToTransferInitiated_loadingIconAppears() {
|
||||
controllerSender.displayChip(moveCloserToStartCast())
|
||||
controllerSender.displayChip(transferInitiated())
|
||||
|
||||
assertThat(getChipView().getLoadingIconVisibility()).isEqualTo(View.VISIBLE)
|
||||
@@ -216,9 +216,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun changeFromTransferSucceededToMoveCloser_undoButtonDisappears() {
|
||||
fun changeFromTransferSucceededToMoveCloserToStart_undoButtonDisappears() {
|
||||
controllerSender.displayChip(transferSucceeded())
|
||||
controllerSender.displayChip(moveCloserToTransfer())
|
||||
controllerSender.displayChip(moveCloserToStartCast())
|
||||
|
||||
assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.GONE)
|
||||
}
|
||||
@@ -240,8 +240,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
/** Helper method providing default parameters to not clutter up the tests. */
|
||||
private fun moveCloserToTransfer() =
|
||||
MoveCloserToTransfer(appIconDrawable, APP_ICON_CONTENT_DESC, DEVICE_NAME)
|
||||
private fun moveCloserToStartCast() =
|
||||
MoveCloserToStartCast(appIconDrawable, APP_ICON_CONTENT_DESC, DEVICE_NAME)
|
||||
|
||||
/** Helper method providing default parameters to not clutter up the tests. */
|
||||
private fun transferInitiated(
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.android.systemui.media.taptotransfer.sender
|
||||
|
||||
import android.media.MediaRoute2Info
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.shared.mediattt.IDeviceSenderCallback
|
||||
import com.android.systemui.util.mockito.any
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
class MediaTttSenderServiceTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var service: MediaTttSenderService
|
||||
private lateinit var callback: IDeviceSenderCallback
|
||||
|
||||
@Mock
|
||||
private lateinit var controller: MediaTttChipControllerSender
|
||||
|
||||
private val mediaInfo = MediaRoute2Info.Builder("id", "Test Name")
|
||||
.addFeature("feature")
|
||||
.build()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
service = MediaTttSenderService(context, controller)
|
||||
callback = IDeviceSenderCallback.Stub.asInterface(service.onBind(null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun closeToReceiverToStartCast_controllerTriggeredWithMoveCloserToStartCastState() {
|
||||
callback.closeToReceiverToStartCast(mediaInfo)
|
||||
|
||||
verify(controller).displayChip(any<MoveCloserToStartCast>())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user