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

Commit 045ed26a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[A11y] Move Magnification key handling to AccessibilityInputFilter" into main

parents 0e690c85 ce5f4174
Loading
Loading
Loading
Loading
+5 −29
Original line number Diff line number Diff line
@@ -122,17 +122,11 @@ public final class KeyGestureEvent {
    public static final int KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW = 69;
    public static final int KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW = 70;
    public static final int KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW = 71;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN = 72;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT = 73;
    public static final int KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION = 74;
    public static final int KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK = 75;
    public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 76;
    public static final int KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB = 77;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT = 78;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT = 79;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP = 80;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN = 81;
    public static final int KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS = 82;
    public static final int KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION = 72;
    public static final int KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK = 73;
    public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 74;
    public static final int KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB = 75;
    public static final int KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS = 76;

    public static final int FLAG_CANCELLED = 1;

@@ -220,16 +214,10 @@ public final class KeyGestureEvent {
            KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW,
            KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW,
            KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW,
            KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN,
            KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT,
            KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION,
            KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK,
            KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
            KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB,
            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT,
            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT,
            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP,
            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN,
            KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS,
    })
    @Retention(RetentionPolicy.SOURCE)
@@ -815,10 +803,6 @@ public final class KeyGestureEvent {
                return "KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW";
            case KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW:
                return "KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW";
            case KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN:
                return "KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN";
            case KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT:
                return "KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT";
            case KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION:
                return "KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION";
            case KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK:
@@ -827,14 +811,6 @@ public final class KeyGestureEvent {
                return "KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW";
            case KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB:
                return "KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB";
            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT:
                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT";
            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT:
                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT";
            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP:
                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP";
            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN:
                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN";
            case KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
                return "KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS";
            default:
+26 −86
Original line number Diff line number Diff line
@@ -21,14 +21,14 @@ import static android.view.MotionEvent.ACTION_SCROLL;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;

import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;

import android.accessibilityservice.AccessibilityTrace;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Region;
import android.hardware.input.InputManager;
import android.hardware.input.KeyGestureEvent;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -46,15 +46,13 @@ import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
import android.view.accessibility.AccessibilityEvent;

import androidx.annotation.Nullable;

import com.android.server.LocalServices;
import com.android.server.accessibility.gestures.TouchExplorer;
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
import com.android.server.accessibility.magnification.FullScreenMagnificationGestureHandler;
import com.android.server.accessibility.magnification.FullScreenMagnificationVibrationHelper;
import com.android.server.accessibility.magnification.MagnificationController;
import com.android.server.accessibility.magnification.MagnificationGestureHandler;
import com.android.server.accessibility.magnification.MagnificationKeyHandler;
import com.android.server.accessibility.magnification.MouseEventHandler;
import com.android.server.accessibility.magnification.WindowMagnificationGestureHandler;
import com.android.server.accessibility.magnification.WindowMagnificationPromptController;
@@ -209,6 +207,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo

    private MouseKeysInterceptor mMouseKeysInterceptor;

    private MagnificationKeyHandler mMagnificationKeyHandler;

    private boolean mInstalled;

    private int mUserId;
@@ -235,74 +235,6 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
     */
    private MotionEvent mLastActiveDeviceMotionEvent = null;

    private boolean mKeyGestureEventHandlerInstalled = false;
    private InputManager.KeyGestureEventHandler mKeyGestureEventHandler =
            new InputManager.KeyGestureEventHandler() {
                @Override
                public boolean handleKeyGestureEvent(
                        @NonNull KeyGestureEvent event,
                        @Nullable IBinder focusedToken) {
                    final boolean complete =
                            event.getAction() == KeyGestureEvent.ACTION_GESTURE_COMPLETE
                                    && !event.isCancelled();

                    // TODO(b/355499907): Receive and handle held key gestures, which can be used
                    // for continuous scaling and panning. In addition, handle multiple pan gestures
                    // at the same time (e.g. user may try to pan diagonally) reasonably, including
                    // decreasing diagonal movement by sqrt(2) to make it appear the same speed
                    // as non-diagonal movement.

                    if (!complete) {
                        return false;
                    }

                    final int gestureType = event.getKeyGestureType();
                    final int displayId = isDisplayIdValid(event.getDisplayId())
                            ? event.getDisplayId() : Display.DEFAULT_DISPLAY;

                    switch (gestureType) {
                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN:
                                mAms.getMagnificationController().scaleMagnificationByStep(
                                        displayId, MagnificationController.ZOOM_DIRECTION_IN);
                            return true;
                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT:
                                mAms.getMagnificationController().scaleMagnificationByStep(
                                        displayId, MagnificationController.ZOOM_DIRECTION_OUT);
                            return true;
                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT:
                            mAms.getMagnificationController().panMagnificationByStep(
                                    displayId, MagnificationController.PAN_DIRECTION_LEFT);
                            return true;
                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT:
                            mAms.getMagnificationController().panMagnificationByStep(
                                    displayId, MagnificationController.PAN_DIRECTION_RIGHT);
                            return true;
                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP:
                            mAms.getMagnificationController().panMagnificationByStep(
                                    displayId, MagnificationController.PAN_DIRECTION_UP);
                            return true;
                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN:
                            mAms.getMagnificationController().panMagnificationByStep(
                                    displayId, MagnificationController.PAN_DIRECTION_DOWN);
                            return true;
                    }
                    return false;
                }

                @Override
                public boolean isKeyGestureSupported(int gestureType) {
                    return switch (gestureType) {
                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN,
                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT,
                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT,
                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT,
                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP,
                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN -> true;
                        default -> false;
                    };
                }
            };

    private static MotionEvent cancelMotion(MotionEvent event) {
        if (event.getActionMasked() == MotionEvent.ACTION_CANCEL
                || event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT
@@ -787,20 +719,11 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
                    });
        }

        if ((mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0
                || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_SINGLE_FINGER_TRIPLE_TAP) != 0)
                || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP) != 0)
                || ((mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0)) {
        if (isAnyMagnificationEnabled()) {
            final MagnificationGestureHandler magnificationGestureHandler =
                    createMagnificationGestureHandler(displayId, displayContext);
            addFirstEventHandler(displayId, magnificationGestureHandler);
            mMagnificationGestureHandler.put(displayId, magnificationGestureHandler);

            if (com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures()
                    && !mKeyGestureEventHandlerInstalled) {
                mInputManager.registerKeyGestureEventHandler(mKeyGestureEventHandler);
                mKeyGestureEventHandlerInstalled = true;
            }
        }

        if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
@@ -817,6 +740,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
        }

        if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) {
            // mKeyboardInterceptor does not forward KeyEvents to other EventStreamTransformations,
            // so it must be the last EventStreamTransformation for key events in the list.
            mKeyboardInterceptor = new KeyboardInterceptor(mAms,
                    LocalServices.getService(WindowManagerPolicy.class));
            // Since the display id of KeyEvent always would be -1 and it would be dispatched to
@@ -832,6 +757,19 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
                    Display.DEFAULT_DISPLAY);
            addFirstEventHandler(Display.DEFAULT_DISPLAY, mMouseKeysInterceptor);
        }

        if (enableTalkbackAndMagnifierKeyGestures() && isAnyMagnificationEnabled()) {
            mMagnificationKeyHandler = new MagnificationKeyHandler(
                    mAms.getMagnificationController());
            addFirstEventHandler(Display.DEFAULT_DISPLAY, mMagnificationKeyHandler);
        }
    }

    private boolean isAnyMagnificationEnabled() {
        return (mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0
                || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_SINGLE_FINGER_TRIPLE_TAP) != 0)
                || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP) != 0)
                || ((mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0);
    }

    /**
@@ -921,9 +859,9 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
            mMouseKeysInterceptor = null;
        }

        if (mKeyGestureEventHandlerInstalled) {
            mInputManager.unregisterKeyGestureEventHandler(mKeyGestureEventHandler);
            mKeyGestureEventHandlerInstalled = false;
        if (mMagnificationKeyHandler != null) {
            mMagnificationKeyHandler.onDestroy();
            mMagnificationKeyHandler = null;
        }
    }

@@ -1365,6 +1303,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
                        joiner.add("AutoclickController");
                    } else if (next instanceof MotionEventInjector) {
                        joiner.add("MotionEventInjector");
                    } else if (next instanceof MagnificationKeyHandler) {
                        joiner.add("MagnificationKeyHandler");
                    }
                    next = next.getNext();
                }
+31 −1
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ import java.util.concurrent.Executor;
 *  is done and before invoking {@link TransitionCallBack#onResult}.
 */
public class MagnificationController implements MagnificationConnectionManager.Callback,
        MagnificationGestureHandler.Callback,
        MagnificationGestureHandler.Callback, MagnificationKeyHandler.Callback,
        FullScreenMagnificationController.MagnificationInfoChangedCallback,
        WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {

@@ -347,6 +347,36 @@ public class MagnificationController implements MagnificationConnectionManager.C
        handleUserInteractionChanged(displayId, mode);
    }

    @Override
    public void onPanMagnificationStart(int displayId,
            @MagnificationController.PanDirection int direction) {
        // TODO(b/355499907): Handle multiple pan gestures at the same time (e.g. user may try to
        // pan diagonally) by decreasing diagonal movement by sqrt(2) to make it appear the same
        // speed as non-diagonal movement.
        panMagnificationByStep(displayId, direction);
    }

    @Override
    public void onPanMagnificationStop(int displayId,
            @MagnificationController.PanDirection int direction) {
        // TODO(b/388847283): Handle held key gestures, which can be used
        // for continuous scaling and panning, until they are released.

    }

    @Override
    public void onScaleMagnificationStart(int displayId,
            @MagnificationController.ZoomDirection int direction) {
        scaleMagnificationByStep(displayId, direction);
    }

    @Override
    public void onScaleMagnificationStop(int displayId,
            @MagnificationController.ZoomDirection int direction) {
        // TODO(b/388847283): Handle held key gestures, which can be used
        // for continuous scaling and panning, until they are released.
    }

    private void handleUserInteractionChanged(int displayId, int mode) {
        if (mMagnificationCapabilities != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
            return;
+133 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.accessibility.magnification;

import android.view.Display;
import android.view.KeyEvent;

import com.android.server.accessibility.BaseEventStreamTransformation;

/*
 * A class that listens to key presses used to control magnification.
 */
public class MagnificationKeyHandler extends BaseEventStreamTransformation {

    /** Callback interface to report that a user is intending to interact with Magnification. */
    public interface Callback {
        /**
         * Called when a keyboard shortcut to pan magnification in direction {@code direction} is
         * pressed by a user. Note that this can be called for multiple directions if multiple
         * arrows are pressed at the same time (e.g. diagonal panning).
         *
         * @param displayId The logical display ID
         * @param direction The direction to start panning
         */
        void onPanMagnificationStart(int displayId,
                @MagnificationController.PanDirection int direction);

        /**
         * Called when a keyboard shortcut to pan magnification in direction {@code direction} is
         * unpressed by a user. Note that this can be called for multiple directions if multiple
         * arrows had been pressed at the same time (e.g. diagonal panning).
         *
         * @param displayId The logical display ID
         * @param direction The direction in which panning stopped
         */
        void onPanMagnificationStop(int displayId,
                @MagnificationController.PanDirection int direction);

        /**
         * Called when a keyboard shortcut to scale magnification in direction `direction` is
         * pressed by a user.
         *
         * @param displayId The logical display ID
         * @param direction The direction in which scaling started
         */
        void onScaleMagnificationStart(int displayId,
                @MagnificationController.ZoomDirection int direction);

        /**
         * Called when a keyboard shortcut to scale magnification in direction `direction` is
         * unpressed by a user.
         *
         * @param displayId The logical display ID
         * @param direction The direction in which scaling stopped
         */
        void onScaleMagnificationStop(int displayId,
                @MagnificationController.ZoomDirection int direction);
    }

    protected final MagnificationKeyHandler.Callback mCallback;

    public MagnificationKeyHandler(Callback callback) {
        mCallback = callback;
    }

    @Override
    public void onKeyEvent(KeyEvent event, int policyFlags) {
        if (!com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures()) {
            // Send to the rest of the handlers.
            super.onKeyEvent(event, policyFlags);
            return;
        }
        boolean modifiersPressed = event.isAltPressed() && event.isMetaPressed();
        if (!modifiersPressed) {
            super.onKeyEvent(event, policyFlags);
            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) {
            int panDirection = switch(keyCode) {
                case KeyEvent.KEYCODE_DPAD_LEFT -> MagnificationController.PAN_DIRECTION_LEFT;
                case KeyEvent.KEYCODE_DPAD_RIGHT -> MagnificationController.PAN_DIRECTION_RIGHT;
                case KeyEvent.KEYCODE_DPAD_UP -> MagnificationController.PAN_DIRECTION_UP;
                default -> MagnificationController.PAN_DIRECTION_DOWN;
            };
            if (isDown) {
                mCallback.onPanMagnificationStart(getDisplayId(event), panDirection);
            } else {
                mCallback.onPanMagnificationStop(getDisplayId(event), panDirection);
            }
            return;
        } else if (keyCode == KeyEvent.KEYCODE_EQUALS || keyCode == KeyEvent.KEYCODE_MINUS) {
            int zoomDirection = MagnificationController.ZOOM_DIRECTION_OUT;
            if (keyCode == KeyEvent.KEYCODE_EQUALS) {
                zoomDirection = MagnificationController.ZOOM_DIRECTION_IN;
            }
            if (isDown) {
                mCallback.onScaleMagnificationStart(getDisplayId(event), zoomDirection);
            } else {
                mCallback.onScaleMagnificationStop(getDisplayId(event), zoomDirection);
            }
            return;
        }

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

    private int getDisplayId(KeyEvent event) {
        // Display ID may be invalid, e.g. for external keyboard attached to phone.
        // In that case, use the default display.
        if (event.getDisplayId() != Display.INVALID_DISPLAY) {
            return event.getDisplayId();
        }
        return Display.DEFAULT_DISPLAY;
    }
}
+14 −19
Original line number Diff line number Diff line
@@ -87,7 +87,20 @@ final class InputGestureManager {
            createKeyTrigger(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON),
            createKeyTrigger(KeyEvent.KEYCODE_X, KeyEvent.META_CTRL_ON),
            createKeyTrigger(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON),
            createKeyTrigger(KeyEvent.KEYCODE_Y, KeyEvent.META_CTRL_ON)
            createKeyTrigger(KeyEvent.KEYCODE_Y, KeyEvent.META_CTRL_ON),
            // Used for magnification viewport control.
            createKeyTrigger(KeyEvent.KEYCODE_MINUS,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON),
            createKeyTrigger(KeyEvent.KEYCODE_EQUALS,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON),
            createKeyTrigger(KeyEvent.KEYCODE_DPAD_LEFT,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON),
            createKeyTrigger(KeyEvent.KEYCODE_DPAD_RIGHT,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON),
            createKeyTrigger(KeyEvent.KEYCODE_DPAD_UP,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON),
            createKeyTrigger(KeyEvent.KEYCODE_DPAD_DOWN,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON)
    ));

    public InputGestureManager(Context context) {
@@ -216,24 +229,6 @@ final class InputGestureManager {
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_T,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_MINUS,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT));
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_EQUALS,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN));
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_LEFT,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT));
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_RIGHT,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT));
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_UP,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP));
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_DOWN,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN));
            systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_M,
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION));
Loading