Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02908b5f authored by Amanda Lin Dietz's avatar Amanda Lin Dietz
Browse files

[A11y Focus API] Update Magnification to use requestRectangleOnScreen API with source

* See go/android-a11y-focus-api for full justification and design.
* Update Magnification to respect the new parameter to the
  requestRectangleOnScreen API behind the flag.
* Update Magnification to differentiate between typing and keyboard
  focus events and move the viewport accordingly.
* Set Magnification follow keyboard focus default to false.
* Update and add unit tests to test both unflagged and flagged
  behavior.

Flag: android.view.accessibility.request_rectangle_with_source
Bug: 391877896
Bug: 391678911
Bug: 391679180
Test: FullScreenMagnificationControllerTest.java,
MagnificationConnectionManagerTest.java, MagnificationControllerTest.java

Change-Id: Iad4ae9800afc9053d6f1c84d79572b9e58b56272
parent 1434d1b8
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -113,6 +113,8 @@ public class FullScreenMagnificationController implements
    private final Rect mTempRect = new Rect();
    // Whether the following typing focus feature for magnification is enabled.
    private boolean mMagnificationFollowTypingEnabled = true;
    // Whether the following keyboard focus feature for magnification is enabled.
    private boolean mMagnificationFollowKeyboardEnabled = false;
    // Whether the always on magnification feature is enabled.
    private boolean mAlwaysOnMagnificationEnabled = false;
    private final DisplayManagerInternal mDisplayManagerInternal;
@@ -1108,9 +1110,9 @@ public class FullScreenMagnificationController implements

    @Override
    public void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
            int bottom) {
            int bottom, int source) {
        synchronized (mLock) {
            if (!mMagnificationFollowTypingEnabled) {
            if (!shouldFollow(source)) {
                return;
            }
            final DisplayMagnification display = mDisplays.get(displayId);
@@ -1129,6 +1131,17 @@ public class FullScreenMagnificationController implements
        }
    }

    private boolean shouldFollow(int source) {
        // Treat UNDEFINED as following typing to preserve behavior for backwards compatibility.
        if (mMagnificationFollowTypingEnabled
                && (source == View.RECTANGLE_ON_SCREEN_REQUEST_SOURCE_TEXT_CURSOR
                || source == View.RECTANGLE_ON_SCREEN_REQUEST_SOURCE_UNDEFINED)) {
            return true;
        }
        return mMagnificationFollowKeyboardEnabled
                && source == View.RECTANGLE_ON_SCREEN_REQUEST_SOURCE_INPUT_FOCUS;
    }

    void setMagnificationFollowTypingEnabled(boolean enabled) {
        mMagnificationFollowTypingEnabled = enabled;
    }
@@ -1137,6 +1150,14 @@ public class FullScreenMagnificationController implements
        return mMagnificationFollowTypingEnabled;
    }

    void setMagnificationFollowKeyboardEnabled(boolean enabled) {
        mMagnificationFollowKeyboardEnabled = enabled;
    }

    boolean isMagnificationFollowKeyboardEnabled() {
        return mMagnificationFollowKeyboardEnabled;
    }

    void setAlwaysOnMagnificationEnabled(boolean enabled) {
        mAlwaysOnMagnificationEnabled = enabled;
    }
+35 −8
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.IMagnificationConnection;
import android.view.accessibility.IMagnificationConnectionCallback;
import android.view.accessibility.MagnificationAnimationCallback;
@@ -144,6 +145,8 @@ public class MagnificationConnectionManager implements
    private SparseArray<WindowMagnifier> mWindowMagnifiers = new SparseArray<>();
    // Whether the following typing focus feature for magnification is enabled.
    private boolean mMagnificationFollowTypingEnabled = true;
    // Whether the following keyboard focus feature for magnification is enabled.
    private boolean mMagnificationFollowKeyboardEnabled = false;
    @GuardedBy("mLock")
    private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray();
    @GuardedBy("mLock")
@@ -408,24 +411,39 @@ public class MagnificationConnectionManager implements

    @Override
    public void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
            int bottom) {
        if (!mMagnificationFollowTypingEnabled) {
            return;
        }

            int bottom, int source) {
        float toCenterX = (float) (left + right) / 2;
        float toCenterY = (float) (top + bottom) / 2;

        synchronized (mLock) {
            if (mIsImeVisibleArray.get(displayId, false)
                    && !isPositionInSourceBounds(displayId, toCenterX, toCenterY)
                    && isTrackingTypingFocusEnabled(displayId)) {
            if (isPositionInSourceBounds(displayId, toCenterX, toCenterY)) {
                return;
            }

            boolean followTyping = shouldFollowTyping(source)
                    && mIsImeVisibleArray.get(displayId, false)
                    && isTrackingTypingFocusEnabled(displayId);
            boolean followKeyboard = shouldFollowKeyboard(source);

            if (followTyping || followKeyboard) {
                moveWindowMagnifierToPositionInternal(displayId, toCenterX, toCenterY,
                        STUB_ANIMATION_CALLBACK);
            }
        }
    }

    private boolean shouldFollowTyping(int source) {
        // Treat UNDEFINED as following typing to preserve behavior for backwards compatibility.
        return mMagnificationFollowTypingEnabled
                && (source == View.RECTANGLE_ON_SCREEN_REQUEST_SOURCE_TEXT_CURSOR
                || source == View.RECTANGLE_ON_SCREEN_REQUEST_SOURCE_UNDEFINED);
    }

    private boolean shouldFollowKeyboard(int source) {
        return mMagnificationFollowKeyboardEnabled
                && source == View.RECTANGLE_ON_SCREEN_REQUEST_SOURCE_INPUT_FOCUS;
    }

    void setMagnificationFollowTypingEnabled(boolean enabled) {
        mMagnificationFollowTypingEnabled = enabled;
    }
@@ -434,6 +452,15 @@ public class MagnificationConnectionManager implements
        return mMagnificationFollowTypingEnabled;
    }

    void setMagnificationFollowKeyboardEnabled(boolean enabled) {
        mMagnificationFollowKeyboardEnabled = enabled;
    }

    boolean isMagnificationFollowKeyboardEnabled() {
        return mMagnificationFollowKeyboardEnabled;
    }


    /**
     * Get the ID of the last service that changed the magnification config.
     *
+9 −2
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.util.SparseIntArray;
import android.util.SparseLongArray;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.MagnificationAnimationCallback;

@@ -744,14 +745,20 @@ public class MagnificationController implements MagnificationConnectionManager.C

    @Override
    public void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
            int bottom) {
            int bottom, int source) {
        WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
                delegate;
        synchronized (mLock) {
            delegate = mAccessibilityCallbacksDelegateArray.get(displayId);
        }
        if (delegate != null) {
            delegate.onRectangleOnScreenRequested(displayId, left, top, right, bottom);
            if (android.view.accessibility.Flags.requestRectangleWithSource()) {
                delegate.onRectangleOnScreenRequested(displayId, left, top, right, bottom, source);
            } else {
                delegate.onRectangleOnScreenRequested(displayId, left, top, right, bottom,
                        View.RECTANGLE_ON_SCREEN_REQUEST_SOURCE_UNDEFINED);
            }

        }
    }

+1 −1
Original line number Diff line number Diff line
@@ -1412,7 +1412,7 @@ final class AccessibilityController {
                }
                final Message m = PooledLambda.obtainMessage(
                        mCallbacks::onRectangleOnScreenRequested, displayId, rectangle.left,
                        rectangle.top, rectangle.right, rectangle.bottom);
                        rectangle.top, rectangle.right, rectangle.bottom, source);
                mHandler.sendMessage(m);
            }
        }
+1 −1
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ public abstract class WindowManagerInternal {
             * @param bottom The rectangle bottom.
             */
            void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
                    int bottom);
                    int bottom, int source);
        }
    }

Loading