diff options
3 files changed, 76 insertions, 1 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 182ed1ebad59..1f17e8ec7b85 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -5952,7 +5952,34 @@ public final class ViewRootImpl implements ViewParent, // If no intersection, set bounds to empty. bounds.setEmpty(); } - return !bounds.isEmpty(); + + if (bounds.isEmpty()) { + return false; + } + + if (android.view.accessibility.Flags.focusRectMinSize()) { + adjustAccessibilityFocusedRectBoundsIfNeeded(bounds); + } + + return true; + } + + /** + * Adjusts accessibility focused rect bounds so that they are not invisible. + * + * <p>Focus bounds smaller than double the stroke width are very hard to see (or invisible). + * Expand the focus bounds if necessary to at least double the stroke width. + * @param bounds The bounds to adjust + */ + @VisibleForTesting + public void adjustAccessibilityFocusedRectBoundsIfNeeded(Rect bounds) { + final int minRectLength = mAccessibilityManager.getAccessibilityFocusStrokeWidth() * 2; + if (bounds.width() < minRectLength || bounds.height() < minRectLength) { + final float missingWidth = Math.max(0, minRectLength - bounds.width()); + final float missingHeight = Math.max(0, minRectLength - bounds.height()); + bounds.inset(-1 * (int) Math.ceil(missingWidth / 2), + -1 * (int) Math.ceil(missingHeight / 2)); + } } private Drawable getAccessibilityFocusedDrawable() { diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig index 8ffae845de1f..820a1fba11ad 100644 --- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig +++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig @@ -96,6 +96,16 @@ flag { flag { namespace: "accessibility" + name: "focus_rect_min_size" + description: "Ensures the a11y focus rect is big enough to be drawn as visible" + bug: "368667566" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + namespace: "accessibility" name: "force_invert_color" description: "Enable force force-dark for smart inversion and dark theme everywhere" bug: "282821643" diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index 632721126714..ed9fc1c9e547 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -71,6 +71,7 @@ import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; import android.os.Binder; import android.os.SystemProperties; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; @@ -82,6 +83,7 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.WindowInsets.Side; import android.view.WindowInsets.Type; +import android.view.accessibility.AccessibilityManager; import androidx.test.annotation.UiThreadTest; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -1628,6 +1630,42 @@ public class ViewRootImplTest { }); } + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_FOCUS_RECT_MIN_SIZE) + public void testAdjustAccessibilityFocusedBounds_largeEnoughBoundsAreUnchanged() { + final int strokeWidth = sContext.getSystemService(AccessibilityManager.class) + .getAccessibilityFocusStrokeWidth(); + final int left, top, width, height; + left = top = 100; + width = height = strokeWidth * 2; + final Rect bounds = new Rect(left, top, left + width, top + height); + final Rect originalBounds = new Rect(bounds); + + mViewRootImpl.adjustAccessibilityFocusedRectBoundsIfNeeded(bounds); + + assertThat(bounds).isEqualTo(originalBounds); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_FOCUS_RECT_MIN_SIZE) + public void testAdjustAccessibilityFocusedBounds_smallBoundsAreExpanded() { + final int strokeWidth = sContext.getSystemService(AccessibilityManager.class) + .getAccessibilityFocusStrokeWidth(); + final int left, top, width, height; + left = top = 100; + width = height = strokeWidth; + final Rect bounds = new Rect(left, top, left + width, top + height); + final Rect originalBounds = new Rect(bounds); + + mViewRootImpl.adjustAccessibilityFocusedRectBoundsIfNeeded(bounds); + + // Bounds should be centered on the same point, but expanded to at least strokeWidth * 2 + assertThat(bounds.centerX()).isEqualTo(originalBounds.centerX()); + assertThat(bounds.centerY()).isEqualTo(originalBounds.centerY()); + assertThat(bounds.width()).isAtLeast(strokeWidth * 2); + assertThat(bounds.height()).isAtLeast(strokeWidth * 2); + } + private boolean setForceDarkSysProp(boolean isForceDarkEnabled) { try { SystemProperties.set( |