Loading packages/SystemUI/res/values/ids.xml +3 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,9 @@ <item type="id" name="row_tag_for_content_view" /> <!-- Chipbar --> <item type="id" name="tag_chipbar_info"/> <!-- Optional cancel button on Keyguard --> <item type="id" name="cancel_button"/> Loading packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt +33 −6 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ import android.os.PowerManager import android.view.Gravity import android.view.MotionEvent import android.view.View import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.widget.TextView import androidx.annotation.IdRes import com.android.internal.widget.CachingIconView import com.android.systemui.Gefingerpoken import com.android.systemui.R Loading Loading @@ -113,6 +116,8 @@ open class ChipbarCoordinator @Inject constructor( } ) currentView.setTag(INFO_TAG, newInfo) // Detect falsing touches on the chip. parent = currentView.requireViewById(R.id.chipbar_root_view) parent.touchHandler = object : Gefingerpoken { Loading Loading @@ -165,8 +170,11 @@ open class ChipbarCoordinator @Inject constructor( } else { "" } currentView.requireViewById<ViewGroup>(R.id.chipbar_inner).contentDescription = "$loadedIconDesc${newInfo.text.loadText(context)}" val chipInnerView = currentView.getInnerView() chipInnerView.contentDescription = "$loadedIconDesc${newInfo.text.loadText(context)}" chipInnerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE maybeGetAccessibilityFocus(newInfo, currentView) // ---- Haptics ---- newInfo.vibrationEffect?.let { Loading @@ -174,23 +182,37 @@ open class ChipbarCoordinator @Inject constructor( } } private fun maybeGetAccessibilityFocus(info: ChipbarInfo?, view: ViewGroup) { // Don't steal focus unless the chipbar has something interactable. // (The chipbar is marked as a live region, so its content will be announced whenever the // content changes.) if (info?.endItem is ChipbarEndItem.Button) { view.getInnerView().requestAccessibilityFocus() } else { view.getInnerView().clearAccessibilityFocus() } } override fun animateViewIn(view: ViewGroup) { val chipInnerView = view.requireViewById<ViewGroup>(R.id.chipbar_inner) ViewHierarchyAnimator.animateAddition( chipInnerView, view.getInnerView(), ViewHierarchyAnimator.Hotspot.TOP, Interpolators.EMPHASIZED_DECELERATE, duration = ANIMATION_IN_DURATION, includeMargins = true, includeFadeIn = true, // We can only request focus once the animation finishes. onAnimationEnd = { chipInnerView.requestAccessibilityFocus() }, onAnimationEnd = { maybeGetAccessibilityFocus(view.getTag(INFO_TAG) as ChipbarInfo?, view) }, ) } override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) { val innerView = view.getInnerView() innerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE ViewHierarchyAnimator.animateRemoval( view.requireViewById<ViewGroup>(R.id.chipbar_inner), innerView, ViewHierarchyAnimator.Hotspot.TOP, Interpolators.EMPHASIZED_ACCELERATE, ANIMATION_OUT_DURATION, Loading @@ -199,6 +221,10 @@ open class ChipbarCoordinator @Inject constructor( ) } private fun ViewGroup.getInnerView(): ViewGroup { return requireViewById(R.id.chipbar_inner) } override fun start() {} override fun getTouchableRegion(view: View, outRect: Rect) { Loading @@ -216,3 +242,4 @@ open class ChipbarCoordinator @Inject constructor( private const val ANIMATION_IN_DURATION = 500L private const val ANIMATION_OUT_DURATION = 250L @IdRes private val INFO_TAG = R.id.tag_chipbar_info Loading
packages/SystemUI/res/values/ids.xml +3 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,9 @@ <item type="id" name="row_tag_for_content_view" /> <!-- Chipbar --> <item type="id" name="tag_chipbar_info"/> <!-- Optional cancel button on Keyguard --> <item type="id" name="cancel_button"/> Loading
packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt +33 −6 Original line number Diff line number Diff line Loading @@ -22,10 +22,13 @@ import android.os.PowerManager import android.view.Gravity import android.view.MotionEvent import android.view.View import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.widget.TextView import androidx.annotation.IdRes import com.android.internal.widget.CachingIconView import com.android.systemui.Gefingerpoken import com.android.systemui.R Loading Loading @@ -113,6 +116,8 @@ open class ChipbarCoordinator @Inject constructor( } ) currentView.setTag(INFO_TAG, newInfo) // Detect falsing touches on the chip. parent = currentView.requireViewById(R.id.chipbar_root_view) parent.touchHandler = object : Gefingerpoken { Loading Loading @@ -165,8 +170,11 @@ open class ChipbarCoordinator @Inject constructor( } else { "" } currentView.requireViewById<ViewGroup>(R.id.chipbar_inner).contentDescription = "$loadedIconDesc${newInfo.text.loadText(context)}" val chipInnerView = currentView.getInnerView() chipInnerView.contentDescription = "$loadedIconDesc${newInfo.text.loadText(context)}" chipInnerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE maybeGetAccessibilityFocus(newInfo, currentView) // ---- Haptics ---- newInfo.vibrationEffect?.let { Loading @@ -174,23 +182,37 @@ open class ChipbarCoordinator @Inject constructor( } } private fun maybeGetAccessibilityFocus(info: ChipbarInfo?, view: ViewGroup) { // Don't steal focus unless the chipbar has something interactable. // (The chipbar is marked as a live region, so its content will be announced whenever the // content changes.) if (info?.endItem is ChipbarEndItem.Button) { view.getInnerView().requestAccessibilityFocus() } else { view.getInnerView().clearAccessibilityFocus() } } override fun animateViewIn(view: ViewGroup) { val chipInnerView = view.requireViewById<ViewGroup>(R.id.chipbar_inner) ViewHierarchyAnimator.animateAddition( chipInnerView, view.getInnerView(), ViewHierarchyAnimator.Hotspot.TOP, Interpolators.EMPHASIZED_DECELERATE, duration = ANIMATION_IN_DURATION, includeMargins = true, includeFadeIn = true, // We can only request focus once the animation finishes. onAnimationEnd = { chipInnerView.requestAccessibilityFocus() }, onAnimationEnd = { maybeGetAccessibilityFocus(view.getTag(INFO_TAG) as ChipbarInfo?, view) }, ) } override fun animateViewOut(view: ViewGroup, onAnimationEnd: Runnable) { val innerView = view.getInnerView() innerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE ViewHierarchyAnimator.animateRemoval( view.requireViewById<ViewGroup>(R.id.chipbar_inner), innerView, ViewHierarchyAnimator.Hotspot.TOP, Interpolators.EMPHASIZED_ACCELERATE, ANIMATION_OUT_DURATION, Loading @@ -199,6 +221,10 @@ open class ChipbarCoordinator @Inject constructor( ) } private fun ViewGroup.getInnerView(): ViewGroup { return requireViewById(R.id.chipbar_inner) } override fun start() {} override fun getTouchableRegion(view: View, outRect: Rect) { Loading @@ -216,3 +242,4 @@ open class ChipbarCoordinator @Inject constructor( private const val ANIMATION_IN_DURATION = 500L private const val ANIMATION_OUT_DURATION = 250L @IdRes private val INFO_TAG = R.id.tag_chipbar_info