From c48d9032baa83abbdf6c804e0cf4a6ebafdd9ae0 Mon Sep 17 00:00:00 2001 From: Robert Horvath Date: Wed, 23 Feb 2022 18:09:46 +0100 Subject: [PATCH] Mark accessibility focus bounds as keep clear area Similar to how input focus can create an automatic keep clear area, this change makes the current accessibility focus rect a keep clear area. Bug: 220108592 Test: atest KeepClearRectsTests Change-Id: I26ca9bf81db31a34046f2453310c1a2f2d8823e8 --- core/java/android/view/ViewRootImpl.java | 32 ++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 2dbf42f93e62b..f459bcaf48cef 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -802,6 +802,7 @@ public final class ViewRootImpl implements ViewParent, private final ViewRootRectTracker mUnrestrictedKeepClearRectsTracker = new ViewRootRectTracker(v -> v.collectUnrestrictedPreferKeepClearRects()); private boolean mHasPendingKeepClearAreaChange; + private Rect mKeepClearAccessibilityFocusRect; private IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection; @@ -4824,13 +4825,27 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendEmptyMessage(MSG_KEEP_CLEAR_RECTS_CHANGED); } - void keepClearRectsChanged() { + private void updateKeepClearForAccessibilityFocusRect() { + if (mViewConfiguration.isPreferKeepClearForFocusEnabled()) { + if (mKeepClearAccessibilityFocusRect == null) { + mKeepClearAccessibilityFocusRect = new Rect(); + } + boolean hasAccessibilityFocus = + getAccessibilityFocusedRect(mKeepClearAccessibilityFocusRect); + if (!hasAccessibilityFocus) { + mKeepClearAccessibilityFocusRect.setEmpty(); + } + mHandler.obtainMessage(MSG_KEEP_CLEAR_RECTS_CHANGED, 1, 0).sendToTarget(); + } + } + + void keepClearRectsChanged(boolean accessibilityFocusRectChanged) { boolean restrictedKeepClearRectsChanged = mKeepClearRectsTracker.computeChanges(); boolean unrestrictedKeepClearRectsChanged = mUnrestrictedKeepClearRectsTracker.computeChanges(); - if ((restrictedKeepClearRectsChanged || unrestrictedKeepClearRectsChanged) - && mView != null) { + if ((restrictedKeepClearRectsChanged || unrestrictedKeepClearRectsChanged + || accessibilityFocusRectChanged) && mView != null) { mHasPendingKeepClearAreaChange = true; // Only report keep clear areas immediately if they have not been reported recently if (!mHandler.hasMessages(MSG_REPORT_KEEP_CLEAR_RECTS)) { @@ -4847,10 +4862,16 @@ public final class ViewRootImpl implements ViewParent, } mHasPendingKeepClearAreaChange = false; - final List restrictedKeepClearRects = mKeepClearRectsTracker.getLastComputedRects(); + List restrictedKeepClearRects = mKeepClearRectsTracker.getLastComputedRects(); final List unrestrictedKeepClearRects = mUnrestrictedKeepClearRectsTracker.getLastComputedRects(); + if (mKeepClearAccessibilityFocusRect != null + && !mKeepClearAccessibilityFocusRect.isEmpty()) { + restrictedKeepClearRects = new ArrayList<>(restrictedKeepClearRects); + restrictedKeepClearRects.add(mKeepClearAccessibilityFocusRect); + } + try { mWindowSession.reportKeepClearAreasChanged(mWindow, restrictedKeepClearRects, unrestrictedKeepClearRects); @@ -5050,6 +5071,7 @@ public final class ViewRootImpl implements ViewParent, // Set the new focus host and node. mAccessibilityFocusedHost = view; mAccessibilityFocusedVirtualView = node; + updateKeepClearForAccessibilityFocusRect(); if (mAttachInfo.mThreadedRenderer != null) { mAttachInfo.mThreadedRenderer.invalidateRoot(); @@ -5638,7 +5660,7 @@ public final class ViewRootImpl implements ViewParent, systemGestureExclusionChanged(); } break; case MSG_KEEP_CLEAR_RECTS_CHANGED: { - keepClearRectsChanged(); + keepClearRectsChanged(/* accessibilityFocusRectChanged= */ msg.arg1 == 1); } break; case MSG_REPORT_KEEP_CLEAR_RECTS: { reportKeepClearAreasChanged();