summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt67
1 files changed, 66 insertions, 1 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index 9c7d644afb7e..8c102ebfb590 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -22,6 +22,7 @@ import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.Point
import android.hardware.input.InputManager
+import android.os.Bundle
import android.os.Handler
import android.view.MotionEvent.ACTION_DOWN
import android.view.SurfaceControl
@@ -29,7 +30,12 @@ import android.view.View
import android.view.View.OnClickListener
import android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
import android.view.WindowManager
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityNodeInfo
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
import android.widget.ImageButton
+import androidx.core.view.ViewCompat
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
import com.android.internal.policy.SystemBarUtils
import com.android.window.flags.Flags
import com.android.wm.shell.R
@@ -67,6 +73,20 @@ internal class AppHandleViewHolder(
captionView.setOnTouchListener(onCaptionTouchListener)
captionHandle.setOnTouchListener(onCaptionTouchListener)
captionHandle.setOnClickListener(onCaptionButtonClickListener)
+ captionHandle.accessibilityDelegate = object : View.AccessibilityDelegate() {
+ override fun sendAccessibilityEvent(host: View, eventType: Int) {
+ when (eventType) {
+ AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
+ AccessibilityEvent.TYPE_VIEW_HOVER_EXIT -> {
+ // Caption Handle itself can't get a11y focus because it's under the status
+ // bar, so pass through TYPE_VIEW_HOVER a11y events to the status bar
+ // input layer, so that it can get a11y focus on the caption handle's behalf
+ statusBarInputLayer?.view?.sendAccessibilityEvent(eventType)
+ }
+ else -> super.sendAccessibilityEvent(host, eventType)
+ }
+ }
+ }
}
override fun bindData(
@@ -134,9 +154,53 @@ internal class AppHandleViewHolder(
captionHandle.dispatchTouchEvent(event)
return@setOnTouchListener true
}
+ setupAppHandleA11y(view)
windowManagerWrapper.updateViewLayout(view, lp)
}
+ private fun setupAppHandleA11y(view: View) {
+ view.accessibilityDelegate = object : View.AccessibilityDelegate() {
+ override fun onInitializeAccessibilityNodeInfo(
+ host: View,
+ info: AccessibilityNodeInfo
+ ) {
+ // Allow the status bar input layer to be a11y clickable so it can interact with
+ // a11y services on behalf of caption handle (due to being under status bar)
+ super.onInitializeAccessibilityNodeInfo(host, info)
+ info.addAction(AccessibilityAction.ACTION_CLICK)
+ host.isClickable = true
+ }
+
+ override fun performAccessibilityAction(
+ host: View,
+ action: Int,
+ args: Bundle?
+ ): Boolean {
+ // Passthrough the a11y click action so the caption handle, so that app handle menu
+ // is opened on a11y click, similar to a real click
+ if (action == AccessibilityAction.ACTION_CLICK.id) {
+ captionHandle.performClick()
+ }
+ return super.performAccessibilityAction(host, action, args)
+ }
+
+ override fun onPopulateAccessibilityEvent(host: View, event: AccessibilityEvent) {
+ super.onPopulateAccessibilityEvent(host, event)
+ // When the status bar input layer is focused, use the content description of the
+ // caption handle so that it appears as "App handle" and not "Unlabelled view"
+ if (event.eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
+ event.text.add(captionHandle.contentDescription)
+ }
+ }
+ }
+
+ // Update a11y action text so that Talkback announces "Press double tap to open app handle
+ // menu" while focused on status bar input layer
+ ViewCompat.replaceAccessibilityAction(
+ view, AccessibilityActionCompat.ACTION_CLICK, "Open app handle menu", null
+ )
+ }
+
private fun updateStatusBarInputLayer(globalPosition: Point) {
statusBarInputLayer?.setPosition(
SurfaceControl.Transaction(),
@@ -173,7 +237,8 @@ internal class AppHandleViewHolder(
return taskInfo.taskDescription
?.let { taskDescription ->
if (Color.alpha(taskDescription.statusBarColor) != 0 &&
- taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
+ taskInfo.windowingMode == WINDOWING_MODE_FREEFORM
+ ) {
Color.valueOf(taskDescription.statusBarColor).luminance() < 0.5
} else {
taskDescription.systemBarsAppearance and APPEARANCE_LIGHT_STATUS_BARS == 0