Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +4 −1 Original line number Diff line number Diff line Loading @@ -1054,6 +1054,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // The user changed. mCurrentUserId = userId; if (mWindowMagnificationMgr != null) { mWindowMagnificationMgr.setUserId(mCurrentUserId); } AccessibilityUserState userState = getCurrentUserStateLocked(); readConfigurationForUserStateLocked(userState); Loading Loading @@ -2641,7 +2644,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub WindowMagnificationManager getWindowMagnificationMgr() { synchronized (mLock) { if (mWindowMagnificationMgr == null) { mWindowMagnificationMgr = new WindowMagnificationManager(); mWindowMagnificationMgr = new WindowMagnificationManager(mContext, mCurrentUserId); } return mWindowMagnificationMgr; } Loading services/accessibility/java/com/android/server/accessibility/gestures/MultiTap.java +4 −2 Original line number Diff line number Diff line Loading @@ -24,8 +24,9 @@ import android.view.ViewConfiguration; /** * This class matches multi-tap gestures. The number of taps for each instance is specified in the * constructor. * @hide */ class MultiTap extends GestureMatcher { public class MultiTap extends GestureMatcher { // Maximum reasonable number of taps. public static final int MAX_TAPS = 10; Loading @@ -40,7 +41,8 @@ class MultiTap extends GestureMatcher { float mBaseX; float mBaseY; MultiTap(Context context, int taps, int gesture, GestureMatcher.StateChangeListener listener) { public MultiTap(Context context, int taps, int gesture, GestureMatcher.StateChangeListener listener) { super(gesture, new Handler(context.getMainLooper()), listener); mTargetTaps = taps; mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop(); Loading services/accessibility/java/com/android/server/accessibility/gestures/MultiTapAndHold.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,9 +22,10 @@ import android.view.MotionEvent; /** * This class matches gestures of the form multi-tap and hold. The number of taps for each instance * is specified in the constructor. * @hide */ class MultiTapAndHold extends MultiTap { MultiTapAndHold( public class MultiTapAndHold extends MultiTap { public MultiTapAndHold( Context context, int taps, int gesture, GestureMatcher.StateChangeListener listener) { super(context, taps, gesture, listener); } Loading services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureMatcher.java +6 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ class MagnificationGestureMatcher { private static final int GESTURE_BASE = 100; public static final int GESTURE_TWO_FINGER_DOWN = GESTURE_BASE + 1; public static final int GESTURE_SWIPE = GESTURE_BASE + 2; public static final int GESTURE_SINGLE_TAP = GESTURE_BASE + 3; public static final int GESTURE_SINGLE_TAP_AND_HOLD = GESTURE_BASE + 4; @IntDef(prefix = {"GESTURE_MAGNIFICATION_"}, value = { GESTURE_TWO_FINGER_DOWN, Loading @@ -55,6 +57,10 @@ class MagnificationGestureMatcher { return "GESTURE_SWIPE"; case GESTURE_TWO_FINGER_DOWN: return "GESTURE_TWO_FINGER_DOWN"; case GESTURE_SINGLE_TAP: return "GESTURE_SINGLE_TAP"; case GESTURE_SINGLE_TAP_AND_HOLD: return "GESTURE_SINGLE_TAP_AND_HOLD"; } return "none"; } Loading services/accessibility/java/com/android/server/accessibility/magnification/MotionEventDispatcherDelegate.java 0 → 100644 +96 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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 static android.view.MotionEvent.ACTION_DOWN; import android.content.Context; import android.os.SystemClock; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; import com.android.internal.R; import java.util.List; /** * Responsible for dispatching delayed events. */ class MotionEventDispatcherDelegate { private static final String TAG = MotionEventDispatcherDelegate.class.getSimpleName(); private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); private final EventDispatcher mEventDispatcher; private final int mMultiTapMaxDelay; private long mLastDelegatedDownEventTime; interface EventDispatcher { void dispatchMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags); } MotionEventDispatcherDelegate(Context context, EventDispatcher eventDispatcher) { mEventDispatcher = eventDispatcher; mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout() + context.getResources().getInteger( R.integer.config_screen_magnification_multi_tap_adjustment); } void sendDelayedMotionEvents(List<MotionEventInfo> delayedEventQueue, long lastDetectingDownEventTime) { if (delayedEventQueue == null) { return; } // Adjust down time to prevent subsequent modules being misleading, and also limit // the maximum offset to mMultiTapMaxDelay to prevent the down time of 2nd tap is // in the future when multi-tap happens. final long offset = Math.min( SystemClock.uptimeMillis() - lastDetectingDownEventTime, mMultiTapMaxDelay); for (MotionEventInfo info: delayedEventQueue) { info.mEvent.setDownTime(info.mEvent.getDownTime() + offset); dispatchMotionEvent(info.mEvent, info.mRawEvent, info.mPolicyFlags); info.recycle(); } } void dispatchMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { // Ensure that the state at the end of delegation is consistent with the last delegated // UP/DOWN event in queue: still delegating if pointer is down, detecting otherwise if (event.getActionMasked() == ACTION_DOWN) { mLastDelegatedDownEventTime = event.getDownTime(); if (DBG) { Log.d(TAG, "dispatchMotionEvent mLastDelegatedDownEventTime time = " + mLastDelegatedDownEventTime); } } // We cache some events to see if the user wants to trigger magnification. // If no magnification is triggered we inject these events with adjusted // time and down time to prevent subsequent transformations being confused // by stale events. After the cached events, which always have a down, are // injected we need to also update the down time of all subsequent non cached // events. All delegated events cached and non-cached are delivered here. if (DBG) { Log.d(TAG, "dispatchMotionEvent original down time = " + event.getDownTime()); } event.setDownTime(mLastDelegatedDownEventTime); mEventDispatcher.dispatchMotionEvent(event, rawEvent, policyFlags); } } Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +4 −1 Original line number Diff line number Diff line Loading @@ -1054,6 +1054,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // The user changed. mCurrentUserId = userId; if (mWindowMagnificationMgr != null) { mWindowMagnificationMgr.setUserId(mCurrentUserId); } AccessibilityUserState userState = getCurrentUserStateLocked(); readConfigurationForUserStateLocked(userState); Loading Loading @@ -2641,7 +2644,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub WindowMagnificationManager getWindowMagnificationMgr() { synchronized (mLock) { if (mWindowMagnificationMgr == null) { mWindowMagnificationMgr = new WindowMagnificationManager(); mWindowMagnificationMgr = new WindowMagnificationManager(mContext, mCurrentUserId); } return mWindowMagnificationMgr; } Loading
services/accessibility/java/com/android/server/accessibility/gestures/MultiTap.java +4 −2 Original line number Diff line number Diff line Loading @@ -24,8 +24,9 @@ import android.view.ViewConfiguration; /** * This class matches multi-tap gestures. The number of taps for each instance is specified in the * constructor. * @hide */ class MultiTap extends GestureMatcher { public class MultiTap extends GestureMatcher { // Maximum reasonable number of taps. public static final int MAX_TAPS = 10; Loading @@ -40,7 +41,8 @@ class MultiTap extends GestureMatcher { float mBaseX; float mBaseY; MultiTap(Context context, int taps, int gesture, GestureMatcher.StateChangeListener listener) { public MultiTap(Context context, int taps, int gesture, GestureMatcher.StateChangeListener listener) { super(gesture, new Handler(context.getMainLooper()), listener); mTargetTaps = taps; mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop(); Loading
services/accessibility/java/com/android/server/accessibility/gestures/MultiTapAndHold.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,9 +22,10 @@ import android.view.MotionEvent; /** * This class matches gestures of the form multi-tap and hold. The number of taps for each instance * is specified in the constructor. * @hide */ class MultiTapAndHold extends MultiTap { MultiTapAndHold( public class MultiTapAndHold extends MultiTap { public MultiTapAndHold( Context context, int taps, int gesture, GestureMatcher.StateChangeListener listener) { super(context, taps, gesture, listener); } Loading
services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureMatcher.java +6 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ class MagnificationGestureMatcher { private static final int GESTURE_BASE = 100; public static final int GESTURE_TWO_FINGER_DOWN = GESTURE_BASE + 1; public static final int GESTURE_SWIPE = GESTURE_BASE + 2; public static final int GESTURE_SINGLE_TAP = GESTURE_BASE + 3; public static final int GESTURE_SINGLE_TAP_AND_HOLD = GESTURE_BASE + 4; @IntDef(prefix = {"GESTURE_MAGNIFICATION_"}, value = { GESTURE_TWO_FINGER_DOWN, Loading @@ -55,6 +57,10 @@ class MagnificationGestureMatcher { return "GESTURE_SWIPE"; case GESTURE_TWO_FINGER_DOWN: return "GESTURE_TWO_FINGER_DOWN"; case GESTURE_SINGLE_TAP: return "GESTURE_SINGLE_TAP"; case GESTURE_SINGLE_TAP_AND_HOLD: return "GESTURE_SINGLE_TAP_AND_HOLD"; } return "none"; } Loading
services/accessibility/java/com/android/server/accessibility/magnification/MotionEventDispatcherDelegate.java 0 → 100644 +96 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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 static android.view.MotionEvent.ACTION_DOWN; import android.content.Context; import android.os.SystemClock; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; import com.android.internal.R; import java.util.List; /** * Responsible for dispatching delayed events. */ class MotionEventDispatcherDelegate { private static final String TAG = MotionEventDispatcherDelegate.class.getSimpleName(); private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); private final EventDispatcher mEventDispatcher; private final int mMultiTapMaxDelay; private long mLastDelegatedDownEventTime; interface EventDispatcher { void dispatchMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags); } MotionEventDispatcherDelegate(Context context, EventDispatcher eventDispatcher) { mEventDispatcher = eventDispatcher; mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout() + context.getResources().getInteger( R.integer.config_screen_magnification_multi_tap_adjustment); } void sendDelayedMotionEvents(List<MotionEventInfo> delayedEventQueue, long lastDetectingDownEventTime) { if (delayedEventQueue == null) { return; } // Adjust down time to prevent subsequent modules being misleading, and also limit // the maximum offset to mMultiTapMaxDelay to prevent the down time of 2nd tap is // in the future when multi-tap happens. final long offset = Math.min( SystemClock.uptimeMillis() - lastDetectingDownEventTime, mMultiTapMaxDelay); for (MotionEventInfo info: delayedEventQueue) { info.mEvent.setDownTime(info.mEvent.getDownTime() + offset); dispatchMotionEvent(info.mEvent, info.mRawEvent, info.mPolicyFlags); info.recycle(); } } void dispatchMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { // Ensure that the state at the end of delegation is consistent with the last delegated // UP/DOWN event in queue: still delegating if pointer is down, detecting otherwise if (event.getActionMasked() == ACTION_DOWN) { mLastDelegatedDownEventTime = event.getDownTime(); if (DBG) { Log.d(TAG, "dispatchMotionEvent mLastDelegatedDownEventTime time = " + mLastDelegatedDownEventTime); } } // We cache some events to see if the user wants to trigger magnification. // If no magnification is triggered we inject these events with adjusted // time and down time to prevent subsequent transformations being confused // by stale events. After the cached events, which always have a down, are // injected we need to also update the down time of all subsequent non cached // events. All delegated events cached and non-cached are delivered here. if (DBG) { Log.d(TAG, "dispatchMotionEvent original down time = " + event.getDownTime()); } event.setDownTime(mLastDelegatedDownEventTime); mEventDispatcher.dispatchMotionEvent(event, rawEvent, policyFlags); } }