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

Commit bb811908 authored by Katie Dektar's avatar Katie Dektar Committed by Android (Google) Code Review
Browse files

Merge "[A11y] Magnification key handler checks if mag is active" into main

parents 933f02b4 64eb92eb
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -455,6 +455,12 @@ public class MagnificationController implements MagnificationConnectionManager.C
        mActivePanDirections = new boolean[]{false, false, false, false};
    }

    @Override
    public boolean isMagnificationActivated(int displayId) {
        return mFullScreenMagnificationController.isActivated(displayId)
                || getMagnificationConnectionManager().isWindowMagnifierEnabled(displayId);
    }

    private void maybeContinuePan() {
        if (mActivePanDisplay == Display.INVALID_DISPLAY) {
            return;
+49 −21
Original line number Diff line number Diff line
@@ -71,6 +71,18 @@ public class MagnificationKeyHandler extends BaseEventStreamTransformation {
         * Called when all keyboard interaction with magnification should be stopped.
         */
        void onKeyboardInteractionStop();

        /**
         * Check for whether magnification is active on the given display. If it is not,
         * there is no need to send scale and zoom events.
         * Note that magnification may be enabled (so this handler is installed) but not
         * activated, for example when the shortcut button is shown or if an A11y service
         * using magnification is active.
         *
         * @param displayId The logical display ID
         * @return true if magnification is activated.
         */
        boolean isMagnificationActivated(int displayId);
    }

    protected final MagnificationKeyHandler.Callback mCallback;
@@ -87,7 +99,9 @@ public class MagnificationKeyHandler extends BaseEventStreamTransformation {
            super.onKeyEvent(event, policyFlags);
            return;
        }
        boolean modifiersPressed = event.isAltPressed() && event.isMetaPressed();
        // Look for exactly Alt and Meta.
        boolean modifiersPressed = event.isAltPressed() && event.isMetaPressed()
                && !event.isCtrlPressed() && !event.isShiftPressed();
        if (!modifiersPressed) {
            super.onKeyEvent(event, policyFlags);
            if (mIsKeyboardInteracting) {
@@ -98,10 +112,28 @@ public class MagnificationKeyHandler extends BaseEventStreamTransformation {
            }
            return;
        }
        boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
                || keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
        boolean isArrowKeyCode = keyCode == KeyEvent.KEYCODE_DPAD_LEFT
                || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
                || keyCode == KeyEvent.KEYCODE_DPAD_UP
                || keyCode == KeyEvent.KEYCODE_DPAD_DOWN;
        boolean isZoomKeyCode = keyCode == KeyEvent.KEYCODE_EQUALS
                || keyCode == KeyEvent.KEYCODE_MINUS;
        if (!isArrowKeyCode && !isZoomKeyCode) {
            // Some other key was pressed.
            super.onKeyEvent(event, policyFlags);
            return;
        }
        int displayId = getDisplayId(event);
        // Check magnification is active only when we know we have the correct keys pressed.
        // This requires `synchronized` which is expensive to do on every key event.
        if (!mCallback.isMagnificationActivated(displayId)) {
            // Magnification isn't active.
            super.onKeyEvent(event, policyFlags);
            return;
        }
        boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
        if (isArrowKeyCode) {
            int panDirection = switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_LEFT -> MagnificationController.PAN_DIRECTION_LEFT;
                case KeyEvent.KEYCODE_DPAD_RIGHT -> MagnificationController.PAN_DIRECTION_RIGHT;
@@ -109,28 +141,24 @@ public class MagnificationKeyHandler extends BaseEventStreamTransformation {
                default -> MagnificationController.PAN_DIRECTION_DOWN;
            };
            if (isDown) {
                mCallback.onPanMagnificationStart(getDisplayId(event), panDirection);
                mCallback.onPanMagnificationStart(displayId, panDirection);
                mIsKeyboardInteracting = true;
            } else {
                mCallback.onPanMagnificationStop(panDirection);
            }
            return;
        } else if (keyCode == KeyEvent.KEYCODE_EQUALS || keyCode == KeyEvent.KEYCODE_MINUS) {
        }
        // Zoom key code.
        int zoomDirection = MagnificationController.ZOOM_DIRECTION_OUT;
        if (keyCode == KeyEvent.KEYCODE_EQUALS) {
            zoomDirection = MagnificationController.ZOOM_DIRECTION_IN;
        }
        if (isDown) {
                mCallback.onScaleMagnificationStart(getDisplayId(event), zoomDirection);
            mCallback.onScaleMagnificationStart(displayId, zoomDirection);
            mIsKeyboardInteracting = true;
        } else {
            mCallback.onScaleMagnificationStop(zoomDirection);
        }
            return;
        }

        // Continue down the eventing chain if this was unused.
        super.onKeyEvent(event, policyFlags);
    }

    private int getDisplayId(KeyEvent event) {
+49 −26
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -68,6 +69,7 @@ public class MagnificationKeyHandlerTest {
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        when(mCallback.isMagnificationActivated(any(Integer.class))).thenReturn(true);
        mMkh = new MagnificationKeyHandler(mCallback);
        mMkh.setNext(mNextHandler);
    }
@@ -77,15 +79,7 @@ public class MagnificationKeyHandlerTest {
        final KeyEvent event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_L, 0, 0);
        mMkh.onKeyEvent(event, 0);

        // No callbacks were called.
        verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onPanMagnificationStop(anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStop(anyInt());
        verify(mCallback, times(0)).onKeyboardInteractionStop();

        // The event was passed on.
        verify(mNextHandler, times(1)).onKeyEvent(event, 0);
        verifySentEventToNext(event);
    }

    @Test
@@ -95,15 +89,7 @@ public class MagnificationKeyHandlerTest {
                        0, KeyEvent.META_ALT_ON);
        mMkh.onKeyEvent(event, 0);

        // No callbacks were called.
        verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onPanMagnificationStop(anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStop(anyInt());
        verify(mCallback, times(0)).onKeyboardInteractionStop();

        // The event was passed on.
        verify(mNextHandler, times(1)).onKeyEvent(event, 0);
        verifySentEventToNext(event);
    }

    @Test
@@ -113,15 +99,41 @@ public class MagnificationKeyHandlerTest {
                        KeyEvent.META_META_ON | KeyEvent.META_ALT_ON);
        mMkh.onKeyEvent(event, 0);

        // No callbacks were called.
        verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onPanMagnificationStop(anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStop(anyInt());
        verify(mCallback, times(0)).onKeyboardInteractionStop();
        verifySentEventToNext(event);
    }

        // The event was passed on.
        verify(mNextHandler, times(1)).onKeyEvent(event, 0);
    @Test
    public void onKeyEvent_arrowKeyPressWithTooManyModifiers_sendToNext() {
        // Add ctrl.
        KeyEvent event =
                new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, 0,
                        KeyEvent.META_META_ON | KeyEvent.META_ALT_ON | KeyEvent.META_CTRL_ON);
        mMkh.onKeyEvent(event, 0);
        verifySentEventToNext(event);

        // Add shift.
        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, 0,
                        KeyEvent.META_META_ON | KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON);
        mMkh.onKeyEvent(event, 0);
        verifySentEventToNext(event);

        // Add ctrl and shift.
        event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, 0,
                KeyEvent.META_META_ON | KeyEvent.META_ALT_ON | KeyEvent.META_CTRL_ON
                        | KeyEvent.META_SHIFT_ON);
        mMkh.onKeyEvent(event, 0);
        verifySentEventToNext(event);
    }

    @Test
    public void onKeyEvent_arrowKeyPressWithoutMagnificationActive_sendToNext() {
        when(mCallback.isMagnificationActivated(any(Integer.class))).thenReturn(false);
        final KeyEvent event =
                new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, 0,
                        KeyEvent.META_META_ON | KeyEvent.META_ALT_ON);
        mMkh.onKeyEvent(event, 0);

        verifySentEventToNext(event);
    }

    @Test
@@ -290,4 +302,15 @@ public class MagnificationKeyHandlerTest {
        verify(mNextHandler, times(0)).onKeyEvent(any(), anyInt());
    }

    private void verifySentEventToNext(KeyEvent event) {
        // No callbacks were called.
        verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onPanMagnificationStop(anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt());
        verify(mCallback, times(0)).onScaleMagnificationStop(anyInt());
        verify(mCallback, times(0)).onKeyboardInteractionStop();

        // The event was passed on.
        verify(mNextHandler, times(1)).onKeyEvent(event, 0);
    }
}