Loading core/java/android/view/ViewRootImpl.java +28 −1 Original line number Diff line number Diff line Loading @@ -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() { Loading core/java/android/view/accessibility/flags/accessibility_flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,16 @@ flag { bug: "303131332" } 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" Loading core/tests/coretests/src/android/view/ViewRootImplTest.java +38 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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( Loading Loading
core/java/android/view/ViewRootImpl.java +28 −1 Original line number Diff line number Diff line Loading @@ -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() { Loading
core/java/android/view/accessibility/flags/accessibility_flags.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,16 @@ flag { bug: "303131332" } 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" Loading
core/tests/coretests/src/android/view/ViewRootImplTest.java +38 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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( Loading