Loading services/accessibility/accessibility.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,16 @@ flag { bug: "322829049" } flag { name: "throttle_motion_events_for_ui_update" namespace: "accessibility" description: "Throttles motion events for requesting the System UI to update magnification UIs." bug: "435498747" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "touch_explorer_a11y_events_include_display_id" namespace: "accessibility" Loading services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +17 −13 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.Flags; import com.android.server.wm.WindowManagerInternal; import java.util.concurrent.Executor; Loading Loading @@ -126,7 +127,7 @@ public class MagnificationController implements MagnificationConnectionManager.C // in multiple directions at once (for example, up + left), tracking last // panned time ensures that panning doesn't occur too frequently. private long mLastPannedTime = 0; private long mLastMouseMoveTriggeredUiChangeTime = 0; private long mLastMotionEventTriggeredUiChangeTime = 0; private boolean mRepeatKeysEnabled = true; private @ZoomDirection int mActiveZoomDirection = ZOOM_DIRECTION_IN; Loading Loading @@ -388,25 +389,17 @@ public class MagnificationController implements MagnificationConnectionManager.C @Override public void onTouchInteractionStart(int displayId, int mode) { // TODO(435498747): Add throttling for touch similarly to mouse events. handleUserInteractionChanged(displayId, mode); handleUserInteractionChanged(displayId, mode, /* isMouse= */ false); } @Override public void onTouchInteractionEnd(int displayId, int mode) { // TODO(435498747): Add throttling for touch similarly to mouse events. handleUserInteractionChanged(displayId, mode); handleUserInteractionChanged(displayId, mode, /* isMouse= */ false); } @Override public void onMouseMove(int displayId, int mode) { final long currentTime = mSystemClock.uptimeMillis(); if (currentTime - mLastMouseMoveTriggeredUiChangeTime < AccessibilityUtils.MAGNIFICATION_HANDLE_UI_CHANGE_INTERVAL_MS) { return; } mLastMouseMoveTriggeredUiChangeTime = currentTime; handleUserInteractionChanged(displayId, mode); handleUserInteractionChanged(displayId, mode, /* isMouse= */ true); } @Override Loading Loading @@ -524,10 +517,21 @@ public class MagnificationController implements MagnificationConnectionManager.C return mInitialKeyboardRepeatIntervalMs; } private void handleUserInteractionChanged(int displayId, int mode) { private void handleUserInteractionChanged(int displayId, int mode, boolean isMouse) { if (mMagnificationCapabilities != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) { return; } // Mouse events are always throttled. Touch events are throttled only when the flag is on. if (isMouse || Flags.throttleMotionEventsForUiUpdate()) { final long currentTime = mSystemClock.uptimeMillis(); if (currentTime - mLastMotionEventTriggeredUiChangeTime < AccessibilityUtils.MAGNIFICATION_HANDLE_UI_CHANGE_INTERVAL_MS) { return; } mLastMotionEventTriggeredUiChangeTime = currentTime; } updateMagnificationUIControls(displayId, mode); } Loading services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -2234,6 +2234,68 @@ public class MagnificationControllerTest { TEST_DISPLAY, MODE_FULLSCREEN); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_THROTTLE_MOTION_EVENTS_FOR_UI_UPDATE) public void onTouchEvent_withThrottleEnabled_shouldRateLimit() throws RemoteException { mMagnificationController.setMagnificationCapabilities( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL); setMagnificationEnabled(MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // The first call should go through and trigger a UI update. mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // Subsequent call within the throttle period should be ignored. mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager, never()).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_THROTTLE_MOTION_EVENTS_FOR_UI_UPDATE) public void onTouchEvent_withThrottleEnabled_shouldNotRateLimitAfterDelay() throws RemoteException { mMagnificationController.setMagnificationCapabilities( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL); setMagnificationEnabled(MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // The first call should go through and trigger a UI update. mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // Advance time past the throttle period. The next call should now go through. mSystemClock.advanceTime(AccessibilityUtils.MAGNIFICATION_HANDLE_UI_CHANGE_INTERVAL_MS + 1); mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); } @Test @DisableFlags(com.android.server.accessibility.Flags.FLAG_THROTTLE_MOTION_EVENTS_FOR_UI_UPDATE) public void onTouchEvent_withThrottleDisabled_shouldNotRateLimit() throws RemoteException { mMagnificationController.setMagnificationCapabilities( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL); setMagnificationEnabled(MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // The first call should go through and trigger a UI update. mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // Subsequent call within the throttle period should also go through. mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); } @Test public void enableWindowMode_showMagnificationButton() throws RemoteException { Loading Loading
services/accessibility/accessibility.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,16 @@ flag { bug: "322829049" } flag { name: "throttle_motion_events_for_ui_update" namespace: "accessibility" description: "Throttles motion events for requesting the System UI to update magnification UIs." bug: "435498747" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "touch_explorer_a11y_events_include_display_id" namespace: "accessibility" Loading
services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +17 −13 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.Flags; import com.android.server.wm.WindowManagerInternal; import java.util.concurrent.Executor; Loading Loading @@ -126,7 +127,7 @@ public class MagnificationController implements MagnificationConnectionManager.C // in multiple directions at once (for example, up + left), tracking last // panned time ensures that panning doesn't occur too frequently. private long mLastPannedTime = 0; private long mLastMouseMoveTriggeredUiChangeTime = 0; private long mLastMotionEventTriggeredUiChangeTime = 0; private boolean mRepeatKeysEnabled = true; private @ZoomDirection int mActiveZoomDirection = ZOOM_DIRECTION_IN; Loading Loading @@ -388,25 +389,17 @@ public class MagnificationController implements MagnificationConnectionManager.C @Override public void onTouchInteractionStart(int displayId, int mode) { // TODO(435498747): Add throttling for touch similarly to mouse events. handleUserInteractionChanged(displayId, mode); handleUserInteractionChanged(displayId, mode, /* isMouse= */ false); } @Override public void onTouchInteractionEnd(int displayId, int mode) { // TODO(435498747): Add throttling for touch similarly to mouse events. handleUserInteractionChanged(displayId, mode); handleUserInteractionChanged(displayId, mode, /* isMouse= */ false); } @Override public void onMouseMove(int displayId, int mode) { final long currentTime = mSystemClock.uptimeMillis(); if (currentTime - mLastMouseMoveTriggeredUiChangeTime < AccessibilityUtils.MAGNIFICATION_HANDLE_UI_CHANGE_INTERVAL_MS) { return; } mLastMouseMoveTriggeredUiChangeTime = currentTime; handleUserInteractionChanged(displayId, mode); handleUserInteractionChanged(displayId, mode, /* isMouse= */ true); } @Override Loading Loading @@ -524,10 +517,21 @@ public class MagnificationController implements MagnificationConnectionManager.C return mInitialKeyboardRepeatIntervalMs; } private void handleUserInteractionChanged(int displayId, int mode) { private void handleUserInteractionChanged(int displayId, int mode, boolean isMouse) { if (mMagnificationCapabilities != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) { return; } // Mouse events are always throttled. Touch events are throttled only when the flag is on. if (isMouse || Flags.throttleMotionEventsForUiUpdate()) { final long currentTime = mSystemClock.uptimeMillis(); if (currentTime - mLastMotionEventTriggeredUiChangeTime < AccessibilityUtils.MAGNIFICATION_HANDLE_UI_CHANGE_INTERVAL_MS) { return; } mLastMotionEventTriggeredUiChangeTime = currentTime; } updateMagnificationUIControls(displayId, mode); } Loading
services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -2234,6 +2234,68 @@ public class MagnificationControllerTest { TEST_DISPLAY, MODE_FULLSCREEN); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_THROTTLE_MOTION_EVENTS_FOR_UI_UPDATE) public void onTouchEvent_withThrottleEnabled_shouldRateLimit() throws RemoteException { mMagnificationController.setMagnificationCapabilities( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL); setMagnificationEnabled(MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // The first call should go through and trigger a UI update. mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // Subsequent call within the throttle period should be ignored. mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager, never()).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); } @Test @EnableFlags(com.android.server.accessibility.Flags.FLAG_THROTTLE_MOTION_EVENTS_FOR_UI_UPDATE) public void onTouchEvent_withThrottleEnabled_shouldNotRateLimitAfterDelay() throws RemoteException { mMagnificationController.setMagnificationCapabilities( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL); setMagnificationEnabled(MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // The first call should go through and trigger a UI update. mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // Advance time past the throttle period. The next call should now go through. mSystemClock.advanceTime(AccessibilityUtils.MAGNIFICATION_HANDLE_UI_CHANGE_INTERVAL_MS + 1); mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); } @Test @DisableFlags(com.android.server.accessibility.Flags.FLAG_THROTTLE_MOTION_EVENTS_FOR_UI_UPDATE) public void onTouchEvent_withThrottleDisabled_shouldNotRateLimit() throws RemoteException { mMagnificationController.setMagnificationCapabilities( Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL); setMagnificationEnabled(MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // The first call should go through and trigger a UI update. mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); clearInvocations(mMagnificationConnectionManager); // Subsequent call within the throttle period should also go through. mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_FULLSCREEN); verify(mMagnificationConnectionManager).showMagnificationButton( TEST_DISPLAY, MODE_FULLSCREEN); } @Test public void enableWindowMode_showMagnificationButton() throws RemoteException { Loading