From 25b7b8520c36990c64203bfd1c8fcb6c6a407981 Mon Sep 17 00:00:00 2001 From: Michael Mikhail Date: Thu, 4 Aug 2022 15:54:11 +0000 Subject: [PATCH] Fix focus at ttt chip Fix talkback focus to be at tap-to-transfer chip. The talkback says the name of the app running and the event. Bug: 229557832 Test: atest MediaTttChipControllerSenderTest Change-Id: If862b0eb9b50533ff184a23b609808611d2be5bd --- .../common/MediaTttChipControllerCommon.kt | 7 ++++-- .../sender/MediaTttChipControllerSender.kt | 24 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) 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 5f478ce325907..9ab83b84277e2 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 @@ -56,7 +56,7 @@ abstract class MediaTttChipControllerCommon( internal val logger: MediaTttLogger, internal val windowManager: WindowManager, private val viewUtil: ViewUtil, - @Main private val mainExecutor: DelayableExecutor, + @Main internal val mainExecutor: DelayableExecutor, private val accessibilityManager: AccessibilityManager, private val configurationController: ConfigurationController, private val powerManager: PowerManager, @@ -205,13 +205,15 @@ abstract class MediaTttChipControllerCommon( * * @param appPackageName the package name of the app playing the media. Will be used to fetch * the app icon and app name if overrides aren't provided. + * + * @return the content description of the icon. */ internal fun setIcon( currentChipView: ViewGroup, appPackageName: String?, appIconDrawableOverride: Drawable? = null, appNameOverride: CharSequence? = null, - ) { + ): CharSequence { val appIconView = currentChipView.requireViewById(R.id.app_icon) val iconInfo = getIconInfo(appPackageName) @@ -224,6 +226,7 @@ abstract class MediaTttChipControllerCommon( appIconView.contentDescription = appNameOverride ?: iconInfo.iconName appIconView.setImageDrawable(appIconDrawableOverride ?: iconInfo.icon) + return appIconView.contentDescription.toString() } /** 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 3ea11b8aa4dd8..b94b8bfabfc11 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 @@ -122,13 +122,12 @@ class MediaTttChipControllerSender @Inject constructor( val chipState = newChipInfo.state // App icon - setIcon(currentChipView, newChipInfo.routeInfo.packageName) + val iconName = setIcon(currentChipView, newChipInfo.routeInfo.packageName) // Text val otherDeviceName = newChipInfo.routeInfo.name.toString() - currentChipView.requireViewById(R.id.text).apply { - text = chipState.getChipTextString(context, otherDeviceName) - } + val chipText = chipState.getChipTextString(context, otherDeviceName) + currentChipView.requireViewById(R.id.text).text = chipText // Loading currentChipView.requireViewById(R.id.loading).visibility = @@ -145,17 +144,29 @@ class MediaTttChipControllerSender @Inject constructor( // Failure currentChipView.requireViewById(R.id.failure_icon).visibility = chipState.isTransferFailure.visibleIfTrue() + + // For accessibility + currentChipView.requireViewById( + R.id.media_ttt_sender_chip_inner + ).contentDescription = "$iconName $chipText" } override fun animateChipIn(chipView: ViewGroup) { + val chipInnerView = chipView.requireViewById(R.id.media_ttt_sender_chip_inner) ViewHierarchyAnimator.animateAddition( - chipView.requireViewById(R.id.media_ttt_sender_chip_inner), + chipInnerView, ViewHierarchyAnimator.Hotspot.TOP, Interpolators.EMPHASIZED_DECELERATE, - duration = 500L, + duration = ANIMATION_DURATION, includeMargins = true, includeFadeIn = true, ) + + // We can only request focus once the animation finishes. + mainExecutor.executeDelayed( + { chipInnerView.requestAccessibilityFocus() }, + ANIMATION_DURATION + ) } override fun removeChip(removalReason: String) { @@ -186,3 +197,4 @@ data class ChipSenderInfo( } const val SENDER_TAG = "MediaTapToTransferSender" +private const val ANIMATION_DURATION = 500L