diff options
9 files changed, 102 insertions, 29 deletions
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 99b283e8ec02..5a86723677b1 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt @@ -71,20 +71,32 @@ class MediaTttCommandLineHelper @Inject constructor( when (args[1]) { MOVE_CLOSER_TO_TRANSFER_COMMAND_NAME -> { mediaTttChipControllerSender.displayChip( - MoveCloserToTransfer(appIconDrawable, otherDeviceName) + MoveCloserToTransfer( + appIconDrawable, APP_ICON_CONTENT_DESCRIPTION, otherDeviceName + ) ) } TRANSFER_INITIATED_COMMAND_NAME -> { val futureTask = FutureTask { fakeUndoRunnable } mediaTttChipControllerSender.displayChip( - TransferInitiated(appIconDrawable, otherDeviceName, futureTask) + TransferInitiated( + appIconDrawable, + APP_ICON_CONTENT_DESCRIPTION, + otherDeviceName, + futureTask + ) ) mainExecutor.executeDelayed({ futureTask.run() }, FUTURE_WAIT_TIME) } TRANSFER_SUCCEEDED_COMMAND_NAME -> { mediaTttChipControllerSender.displayChip( - TransferSucceeded(appIconDrawable, otherDeviceName, fakeUndoRunnable) + TransferSucceeded( + appIconDrawable, + APP_ICON_CONTENT_DESCRIPTION, + otherDeviceName, + fakeUndoRunnable + ) ) } else -> { @@ -118,7 +130,9 @@ class MediaTttCommandLineHelper @Inject constructor( /** A command to DISPLAY the media ttt chip on the RECEIVER device. */ inner class AddChipCommandReceiver : Command { override fun execute(pw: PrintWriter, args: List<String>) { - mediaTttChipControllerReceiver.displayChip(ChipStateReceiver(appIconDrawable)) + mediaTttChipControllerReceiver.displayChip( + ChipStateReceiver(appIconDrawable, APP_ICON_CONTENT_DESCRIPTION) + ) } override fun help(pw: PrintWriter) { pw.println("Usage: adb shell cmd statusbar $ADD_CHIP_COMMAND_RECEIVER_TAG") @@ -156,4 +170,5 @@ val TRANSFER_INITIATED_COMMAND_NAME = TransferInitiated::class.simpleName!! val TRANSFER_SUCCEEDED_COMMAND_NAME = TransferSucceeded::class.simpleName!! private const val FUTURE_WAIT_TIME = 2000L +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 3b429c887796..67721a543427 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 @@ -99,6 +99,7 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>( internal fun setIcon(chipState: T, currentChipView: ViewGroup) { currentChipView.findViewById<CachingIconView>(R.id.app_icon).apply { this.setImageDrawable(chipState.appIconDrawable) + this.contentDescription = chipState.appIconContentDescription } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt index 1e475a5e7c82..c510cbba9c35 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt @@ -22,7 +22,9 @@ import android.graphics.drawable.Drawable * A superclass chip state that will be subclassed by the sender chip and receiver chip. * * @property appIconDrawable a drawable representing the icon of the app playing the media. + * @property appIconContentDescription a string to use as the content description for the icon. */ open class MediaTttChipState( - internal val appIconDrawable: Drawable + internal val appIconDrawable: Drawable, + internal val appIconContentDescription: String ) diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt index 5397235e0137..df6b93431c93 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt @@ -24,5 +24,6 @@ import com.android.systemui.media.taptotransfer.common.MediaTttChipState * the receiver device. */ class ChipStateReceiver( - appIconDrawable: Drawable -) : MediaTttChipState(appIconDrawable) + appIconDrawable: Drawable, + appIconContentDescription: String +) : MediaTttChipState(appIconDrawable, appIconContentDescription) diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt index 24943b9e2a1e..b1f6faaba924 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt @@ -34,9 +34,10 @@ import java.util.concurrent.Future */ sealed class ChipStateSender( appIconDrawable: Drawable, + appIconContentDescription: String, @StringRes internal val chipText: Int, internal val otherDeviceName: String, -) : MediaTttChipState(appIconDrawable) +) : MediaTttChipState(appIconDrawable, appIconContentDescription) /** * A state representing that the two devices are close but not close enough to initiate a transfer. @@ -44,8 +45,14 @@ sealed class ChipStateSender( */ class MoveCloserToTransfer( appIconDrawable: Drawable, + appIconContentDescription: String, otherDeviceName: String, -) : ChipStateSender(appIconDrawable, R.string.media_move_closer_to_transfer, otherDeviceName) +) : ChipStateSender( + appIconDrawable, + appIconContentDescription, + R.string.media_move_closer_to_transfer, + otherDeviceName +) /** * A state representing that a transfer has been initiated (but not completed). @@ -57,9 +64,15 @@ class MoveCloserToTransfer( */ class TransferInitiated( appIconDrawable: Drawable, + appIconContentDescription: String, otherDeviceName: String, val future: Future<Runnable?> -) : ChipStateSender(appIconDrawable, R.string.media_transfer_playing, otherDeviceName) +) : ChipStateSender( + appIconDrawable, + appIconContentDescription, + R.string.media_transfer_playing, + otherDeviceName +) /** * A state representing that a transfer has been successfully completed. @@ -69,6 +82,11 @@ class TransferInitiated( */ class TransferSucceeded( appIconDrawable: Drawable, + appIconContentDescription: String, otherDeviceName: String, val undoRunnable: Runnable? = null -) : ChipStateSender(appIconDrawable, R.string.media_transfer_playing, otherDeviceName) +) : ChipStateSender(appIconDrawable, + appIconContentDescription, + R.string.media_transfer_playing, + otherDeviceName +) diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt index fce4b98f9abe..77d3d70fc98c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt @@ -93,7 +93,10 @@ class MediaTttChipControllerSender @Inject constructor( mainExecutor.execute { displayChip( TransferSucceeded( - chipState.appIconDrawable, chipState.otherDeviceName, undoRunnable + chipState.appIconDrawable, + chipState.appIconContentDescription, + chipState.otherDeviceName, + undoRunnable ) ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt index b74ba2646ba3..927ca7a34cf8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt @@ -19,14 +19,18 @@ package com.android.systemui.media.taptotransfer.common import android.content.Context import android.graphics.drawable.Drawable import android.graphics.drawable.Icon +import android.view.View import android.view.ViewGroup import android.view.WindowManager +import android.widget.ImageView import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.any +import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test +import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.reset @@ -50,24 +54,24 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() { @Test fun displayChip_chipAdded() { - controllerCommon.displayChip(MediaTttChipState(appIconDrawable)) + controllerCommon.displayChip(getState()) verify(windowManager).addView(any(), any()) } @Test fun displayChip_twice_chipNotAddedTwice() { - controllerCommon.displayChip(MediaTttChipState(appIconDrawable)) + controllerCommon.displayChip(getState()) reset(windowManager) - controllerCommon.displayChip(MediaTttChipState(appIconDrawable)) + controllerCommon.displayChip(getState()) verify(windowManager, never()).addView(any(), any()) } @Test fun removeChip_chipRemoved() { // First, add the chip - controllerCommon.displayChip(MediaTttChipState(appIconDrawable)) + controllerCommon.displayChip(getState()) // Then, remove it controllerCommon.removeChip() @@ -82,6 +86,29 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() { verify(windowManager, never()).removeView(any()) } + @Test + fun setIcon_viewHasIconAndContentDescription() { + controllerCommon.displayChip(getState()) + val chipView = getChipView() + val drawable = Icon.createWithResource(context, R.drawable.ic_cake).loadDrawable(context) + val contentDescription = "test description" + + controllerCommon.setIcon(MediaTttChipState(drawable, contentDescription), chipView) + + assertThat(chipView.getAppIconView().drawable).isEqualTo(drawable) + assertThat(chipView.getAppIconView().contentDescription).isEqualTo(contentDescription) + } + + private fun getState() = MediaTttChipState(appIconDrawable, APP_ICON_CONTENT_DESCRIPTION) + + private fun getChipView(): ViewGroup { + val viewCaptor = ArgumentCaptor.forClass(View::class.java) + verify(windowManager).addView(viewCaptor.capture(), any()) + return viewCaptor.value as ViewGroup + } + + private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon) + inner class TestControllerCommon( context: Context, windowManager: WindowManager @@ -92,3 +119,5 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() { } } } + +private const val APP_ICON_CONTENT_DESCRIPTION = "Content description" diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt index 2ff472fc7abe..afaab807c74c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt @@ -16,7 +16,6 @@ package com.android.systemui.media.taptotransfer.receiver -import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.view.View import android.view.ViewGroup @@ -50,10 +49,12 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { @Test fun displayChip_chipContainsIcon() { val drawable = Icon.createWithResource(context, R.drawable.ic_cake).loadDrawable(context) + val contentDescription = "Test description" - controllerReceiver.displayChip(ChipStateReceiver(drawable)) + controllerReceiver.displayChip(ChipStateReceiver(drawable, contentDescription)) - assertThat(getChipView().getAppIconDrawable()).isEqualTo(drawable) + assertThat(getChipView().getAppIconView().drawable).isEqualTo(drawable) + assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(contentDescription) } private fun getChipView(): ViewGroup { @@ -62,6 +63,5 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() { return viewCaptor.value as ViewGroup } - private fun ViewGroup.getAppIconDrawable(): Drawable = - (this.requireViewById<ImageView>(R.id.app_icon)).drawable + private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt index 028ec55ce28e..caef5b901e0f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt @@ -70,7 +70,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { controllerSender.displayChip(moveCloserToTransfer()) val chipView = getChipView() - assertThat(chipView.getAppIconDrawable()).isEqualTo(appIconDrawable) + assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconDrawable) + assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_ICON_CONTENT_DESC) assertThat(chipView.getChipText()).contains(DEVICE_NAME) assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE) assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE) @@ -85,7 +86,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { // Assert we're still in the loading state val chipView = getChipView() - assertThat(chipView.getAppIconDrawable()).isEqualTo(appIconDrawable) + assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconDrawable) + assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_ICON_CONTENT_DESC) assertThat(chipView.getChipText()).contains(DEVICE_NAME) assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.VISIBLE) assertThat(chipView.getUndoButton().visibility).isEqualTo(View.GONE) @@ -155,7 +157,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { controllerSender.displayChip(transferSucceeded()) val chipView = getChipView() - assertThat(chipView.getAppIconDrawable()).isEqualTo(appIconDrawable) + assertThat(chipView.getAppIconView().drawable).isEqualTo(appIconDrawable) + assertThat(chipView.getAppIconView().contentDescription).isEqualTo(APP_ICON_CONTENT_DESC) assertThat(chipView.getChipText()).contains(DEVICE_NAME) assertThat(chipView.getLoadingIconVisibility()).isEqualTo(View.GONE) } @@ -220,8 +223,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { assertThat(getChipView().getUndoButton().visibility).isEqualTo(View.GONE) } - private fun LinearLayout.getAppIconDrawable(): Drawable = - (this.requireViewById<ImageView>(R.id.app_icon)).drawable + private fun LinearLayout.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon) private fun LinearLayout.getChipText(): String = (this.requireViewById<TextView>(R.id.text)).text as String @@ -238,20 +240,22 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { } /** Helper method providing default parameters to not clutter up the tests. */ - private fun moveCloserToTransfer() = MoveCloserToTransfer(appIconDrawable, DEVICE_NAME) + private fun moveCloserToTransfer() = + MoveCloserToTransfer(appIconDrawable, APP_ICON_CONTENT_DESC, DEVICE_NAME) /** Helper method providing default parameters to not clutter up the tests. */ private fun transferInitiated( future: Future<Runnable?> = TEST_FUTURE - ) = TransferInitiated(appIconDrawable, DEVICE_NAME, future) + ) = TransferInitiated(appIconDrawable, APP_ICON_CONTENT_DESC, DEVICE_NAME, future) /** Helper method providing default parameters to not clutter up the tests. */ private fun transferSucceeded( undoRunnable: Runnable? = null - ) = TransferSucceeded(appIconDrawable, DEVICE_NAME, undoRunnable) + ) = TransferSucceeded(appIconDrawable, APP_ICON_CONTENT_DESC, DEVICE_NAME, undoRunnable) } private const val DEVICE_NAME = "My Tablet" +private const val APP_ICON_CONTENT_DESC = "Content description" // Use a settable future that hasn't yet been set so that we don't immediately switch to the success // state. private val TEST_FUTURE: SettableFuture<Runnable?> = SettableFuture.create() |