diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 52a6dc143df74..e59a3d633cfd0 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -193,6 +193,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private static final int OWN_PROCESS_ID = android.os.Process.myPid(); + public static final int INVALID_SERVICE_ID = -1; + // Each service has an ID. Also provide one for magnification gesture handling public static final int MAGNIFICATION_GESTURE_HANDLER_ID = 0; diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java index 38615feeba48b..72bc8503b7a53 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java @@ -19,6 +19,8 @@ package com.android.server.accessibility.magnification; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL; import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK; +import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID; + import android.animation.Animator; import android.animation.ValueAnimator; import android.annotation.NonNull; @@ -117,8 +119,7 @@ public class FullScreenMagnificationController implements private final int mDisplayId; - private static final int INVALID_ID = -1; - private int mIdOfLastServiceToMagnify = INVALID_ID; + private int mIdOfLastServiceToMagnify = INVALID_SERVICE_ID; private boolean mMagnificationActivated = false; DisplayMagnification(int displayId) { @@ -425,7 +426,7 @@ public class FullScreenMagnificationController implements } final float scale = getScale(); - offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_ID); + offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_SERVICE_ID); } } @@ -472,7 +473,7 @@ public class FullScreenMagnificationController implements spec.clear(); onMagnificationChangedLocked(); } - mIdOfLastServiceToMagnify = INVALID_ID; + mIdOfLastServiceToMagnify = INVALID_SERVICE_ID; mForceShowMagnifiableBounds = false; sendSpecToAnimation(spec, animationCallback); return changed; @@ -519,7 +520,7 @@ public class FullScreenMagnificationController implements } final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY); sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback); - if (isMagnifying() && (id != INVALID_ID)) { + if (isMagnifying() && (id != INVALID_SERVICE_ID)) { mIdOfLastServiceToMagnify = id; mMagnificationInfoChangedCallback.onRequestMagnificationSpec(mDisplayId, mIdOfLastServiceToMagnify); @@ -583,7 +584,7 @@ public class FullScreenMagnificationController implements if (updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY)) { onMagnificationChangedLocked(); } - if (id != INVALID_ID) { + if (id != INVALID_SERVICE_ID) { mIdOfLastServiceToMagnify = id; } sendSpecToAnimation(mCurrentMagnificationSpec, null); diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java index 791da694c8117..a63dd005f988e 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java @@ -22,6 +22,8 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW; import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK; +import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID; + import android.accessibilityservice.MagnificationConfig; import android.annotation.NonNull; import android.annotation.Nullable; @@ -240,9 +242,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb * @param config The targeting magnification config * @param animate {@code true} to animate the transition, {@code false} * to transition immediately + * @param id The ID of the service requesting the change */ public void transitionMagnificationConfigMode(int displayId, MagnificationConfig config, - boolean animate) { + boolean animate, int id) { synchronized (mLock) { final int targetMode = config.getMode(); final PointF currentBoundsCenter = getCurrentMagnificationBoundsCenterLocked(displayId, @@ -273,7 +276,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb screenMagnificationController.reset(displayId, false); windowMagnificationMgr.enableWindowMagnification(displayId, scale, magnificationCenter.x, magnificationCenter.y, - animate ? STUB_ANIMATION_CALLBACK : null); + animate ? STUB_ANIMATION_CALLBACK : null, id); } else if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) { windowMagnificationMgr.disableWindowMagnification(displayId, false, null); if (!screenMagnificationController.isRegistered(displayId)) { @@ -281,7 +284,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb } screenMagnificationController.setScaleAndCenter(displayId, scale, magnificationCenter.x, magnificationCenter.y, animate, - AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID); + id); } } } @@ -337,7 +340,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb public void onRequestMagnificationSpec(int displayId, int serviceId) { final WindowMagnificationManager windowMagnificationManager; synchronized (mLock) { - if (serviceId == AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID) { + if (serviceId == MAGNIFICATION_GESTURE_HANDLER_ID) { return; } updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); @@ -718,11 +721,12 @@ public class MagnificationController implements WindowMagnificationManager.Callb } fullScreenMagnificationController.setScaleAndCenter(mDisplayId, mCurrentScale, mCurrentCenter.x, mCurrentCenter.y, mAnimate, - AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID); + MAGNIFICATION_GESTURE_HANDLER_ID); } else { getWindowMagnificationMgr().enableWindowMagnification(mDisplayId, mCurrentScale, mCurrentCenter.x, - mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null); + mCurrentCenter.y, mAnimate ? STUB_ANIMATION_CALLBACK : null, + MAGNIFICATION_GESTURE_HANDLER_ID); } } } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java index 7a525ee23d276..40f77b04d5de4 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java @@ -99,7 +99,7 @@ public class MagnificationProcessor { */ public boolean setMagnificationConfig(int displayId, @NonNull MagnificationConfig config, boolean animate, int id) { - if (transitionModeIfNeeded(displayId, config, animate)) { + if (transitionModeIfNeeded(displayId, config, animate, id)) { return true; } @@ -114,7 +114,8 @@ public class MagnificationProcessor { } else if (configMode == MAGNIFICATION_MODE_WINDOW) { return mController.getWindowMagnificationMgr().enableWindowMagnification(displayId, config.getScale(), config.getCenterX(), config.getCenterY(), - animate ? STUB_ANIMATION_CALLBACK : null); + animate ? STUB_ANIMATION_CALLBACK : null, + id); } return false; } @@ -136,13 +137,13 @@ public class MagnificationProcessor { * mode when the controlling mode is unchanged or the controlling magnifier is not activated. */ private boolean transitionModeIfNeeded(int displayId, MagnificationConfig config, - boolean animate) { + boolean animate, int id) { int currentMode = getControllingMode(displayId); if (currentMode == config.getMode() || !mController.hasDisableMagnificationCallback(displayId)) { return false; } - mController.transitionMagnificationConfigMode(displayId, config, animate); + mController.transitionMagnificationConfigMode(displayId, config, animate, id); return true; } @@ -237,7 +238,8 @@ public class MagnificationProcessor { if (mode == MAGNIFICATION_MODE_FULLSCREEN) { return mController.getFullScreenMagnificationController().reset(displayId, animate); } else if (mode == MAGNIFICATION_MODE_WINDOW) { - return mController.getWindowMagnificationMgr().reset(displayId); + return mController.getWindowMagnificationMgr().disableWindowMagnification(displayId, + false, animate ? STUB_ANIMATION_CALLBACK : null); } return false; } @@ -256,11 +258,15 @@ public class MagnificationProcessor { } /** - * {@link FullScreenMagnificationController#resetIfNeeded(int, boolean)} + * Resets all the magnifiers on all the displays. + * Called when the a11y service connection that has changed the current magnification spec is + * unbound or the binder died. + * + * @param connectionId The connection id */ - // TODO: support window magnification public void resetAllIfNeeded(int connectionId) { mController.getFullScreenMagnificationController().resetAllIfNeeded(connectionId); + mController.getWindowMagnificationMgr().resetAllIfNeeded(connectionId); } /** diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java index 3f6ff25dafe56..336f0bbbe5185 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java @@ -20,6 +20,9 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNI import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK; import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK; +import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID; +import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -253,7 +256,26 @@ public class WindowMagnificationManager implements } mWindowMagnifiers.clear(); } + } + /** + * Resets the window magnifier on all displays that had been controlled by the + * specified service connection. Called when the service connection is unbound + * or binder died. + * + * @param connectionId The connection id + */ + public void resetAllIfNeeded(int connectionId) { + synchronized (mLock) { + for (int i = 0; i < mWindowMagnifiers.size(); i++) { + final WindowMagnifier magnifier = mWindowMagnifiers.valueAt(i); + if (magnifier != null + && magnifier.mEnabled + && connectionId == magnifier.getIdOfLastServiceToControl()) { + magnifier.disableWindowMagnificationInternal(null); + } + } + } } private void resetWindowMagnifiers() { @@ -310,7 +332,7 @@ public class WindowMagnificationManager implements public boolean enableWindowMagnification(int displayId, float scale, float centerX, float centerY) { return enableWindowMagnification(displayId, scale, centerX, centerY, - STUB_ANIMATION_CALLBACK); + STUB_ANIMATION_CALLBACK, MAGNIFICATION_GESTURE_HANDLER_ID); } /** @@ -324,12 +346,13 @@ public class WindowMagnificationManager implements * @param centerY The screen-relative Y coordinate around which to center for magnification, * or {@link Float#NaN} to leave unchanged. * @param animationCallback Called when the animation result is valid. + * @param id The connection ID * @return {@code true} if the magnification is enabled successfully. */ public boolean enableWindowMagnification(int displayId, float scale, float centerX, - float centerY, @Nullable MagnificationAnimationCallback animationCallback) { + float centerY, @Nullable MagnificationAnimationCallback animationCallback, int id) { return enableWindowMagnification(displayId, scale, centerX, centerY, animationCallback, - WINDOW_POSITION_AT_CENTER); + WINDOW_POSITION_AT_CENTER, id); } /** @@ -348,7 +371,7 @@ public class WindowMagnificationManager implements public boolean enableWindowMagnification(int displayId, float scale, float centerX, float centerY, @WindowPosition int windowPosition) { return enableWindowMagnification(displayId, scale, centerX, centerY, - STUB_ANIMATION_CALLBACK, windowPosition); + STUB_ANIMATION_CALLBACK, windowPosition, MAGNIFICATION_GESTURE_HANDLER_ID); } /** @@ -367,7 +390,7 @@ public class WindowMagnificationManager implements */ public boolean enableWindowMagnification(int displayId, float scale, float centerX, float centerY, @Nullable MagnificationAnimationCallback animationCallback, - @WindowPosition int windowPosition) { + @WindowPosition int windowPosition, int id) { final boolean enabled; boolean previousEnabled; synchronized (mLock) { @@ -380,7 +403,7 @@ public class WindowMagnificationManager implements } previousEnabled = magnifier.mEnabled; enabled = magnifier.enableWindowMagnificationInternal(scale, centerX, centerY, - animationCallback, windowPosition); + animationCallback, windowPosition, id); } if (enabled && !previousEnabled) { @@ -394,9 +417,10 @@ public class WindowMagnificationManager implements * * @param displayId The logical display id. * @param clear {@true} Clears the state of window magnification. + * @return {@code true} if the magnification is turned to be disabled successfully */ - void disableWindowMagnification(int displayId, boolean clear) { - disableWindowMagnification(displayId, clear, STUB_ANIMATION_CALLBACK); + boolean disableWindowMagnification(int displayId, boolean clear) { + return disableWindowMagnification(displayId, clear, STUB_ANIMATION_CALLBACK); } /** @@ -405,14 +429,15 @@ public class WindowMagnificationManager implements * @param displayId The logical display id. * @param clear {@true} Clears the state of window magnification. * @param animationCallback Called when the animation result is valid. + * @return {@code true} if the magnification is turned to be disabled successfully */ - void disableWindowMagnification(int displayId, boolean clear, + public boolean disableWindowMagnification(int displayId, boolean clear, MagnificationAnimationCallback animationCallback) { final boolean disabled; synchronized (mLock) { WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); if (magnifier == null || mConnectionWrapper == null) { - return; + return false; } disabled = magnifier.disableWindowMagnificationInternal(animationCallback); if (clear) { @@ -423,6 +448,7 @@ public class WindowMagnificationManager implements if (disabled) { mCallback.onWindowMagnificationActivationState(displayId, false); } + return disabled; } /** @@ -490,7 +516,7 @@ public class WindowMagnificationManager implements public float getScale(int displayId) { synchronized (mLock) { WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { + if (magnifier == null || !magnifier.mEnabled) { return 1.0f; } return magnifier.getScale(); @@ -548,7 +574,7 @@ public class WindowMagnificationManager implements public float getCenterX(int displayId) { synchronized (mLock) { WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { + if (magnifier == null || !magnifier.mEnabled) { return Float.NaN; } return magnifier.getCenterX(); @@ -564,7 +590,7 @@ public class WindowMagnificationManager implements public float getCenterY(int displayId) { synchronized (mLock) { WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { + if (magnifier == null || !magnifier.mEnabled) { return Float.NaN; } return magnifier.getCenterY(); @@ -581,7 +607,7 @@ public class WindowMagnificationManager implements public void getMagnificationSourceBounds(int displayId, @NonNull Region outRegion) { synchronized (mLock) { WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { + if (magnifier == null || !magnifier.mEnabled) { outRegion.setEmpty(); } else { outRegion.set(magnifier.mSourceBounds); @@ -589,24 +615,6 @@ public class WindowMagnificationManager implements } } - /** - * Resets the magnification scale and center. - * - * @param displayId The logical display id. - * @return {@code true} if the magnification spec changed, {@code false} if - * the spec did not change - */ - public boolean reset(int displayId) { - synchronized (mLock) { - WindowMagnifier magnifier = mWindowMagnifiers.get(displayId); - if (magnifier == null) { - return false; - } - magnifier.reset(); - return true; - } - } - /** * Creates the windowMagnifier based on the specified display and stores it. * @@ -722,6 +730,9 @@ public class WindowMagnificationManager implements /** * A class manipulates window magnification per display and contains the magnification * information. + *

+ * This class requires to hold the lock when controlling the magnifier. + *

*/ private static class WindowMagnifier { @@ -735,6 +746,8 @@ public class WindowMagnificationManager implements // The magnified bounds on the screen. private final Rect mSourceBounds = new Rect(); + private int mIdOfLastServiceToControl = INVALID_SERVICE_ID; + private PointF mMagnificationFrameOffsetRatio = new PointF(0f, 0f); WindowMagnifier(int displayId, WindowMagnificationManager windowMagnificationManager) { @@ -745,7 +758,7 @@ public class WindowMagnificationManager implements @GuardedBy("mLock") boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY, @Nullable MagnificationAnimationCallback animationCallback, - @WindowPosition int windowPosition) { + @WindowPosition int windowPosition, int id) { // Handle defaults. The scale may be NAN when just updating magnification center. if (Float.isNaN(scale)) { scale = getScale(); @@ -757,7 +770,7 @@ public class WindowMagnificationManager implements mMagnificationFrameOffsetRatio.y, animationCallback)) { mScale = normScale; mEnabled = true; - + mIdOfLastServiceToControl = id; return true; } return false; @@ -785,7 +798,7 @@ public class WindowMagnificationManager implements if (mWindowMagnificationManager.disableWindowMagnificationInternal( mDisplayId, animationResultCallback)) { mEnabled = false; - + mIdOfLastServiceToControl = INVALID_SERVICE_ID; return true; } return false; @@ -813,6 +826,13 @@ public class WindowMagnificationManager implements mBounds.set(rect); } + /** + * Returns the ID of the last service that changed the magnification config. + */ + int getIdOfLastServiceToControl() { + return mIdOfLastServiceToControl; + } + @GuardedBy("mLock") int pointersInWindow(MotionEvent motionEvent) { int count = 0; @@ -840,6 +860,8 @@ public class WindowMagnificationManager implements @GuardedBy("mLock") void reset() { mEnabled = false; + mIdOfLastServiceToControl = INVALID_SERVICE_ID; + mSourceBounds.setEmpty(); } @GuardedBy("mLock") @@ -849,12 +871,12 @@ public class WindowMagnificationManager implements @GuardedBy("mLock") float getCenterX() { - return mEnabled ? mSourceBounds.exactCenterX() : Float.NaN; + return mSourceBounds.exactCenterX(); } @GuardedBy("mLock") float getCenterY() { - return mEnabled ? mSourceBounds.exactCenterY() : Float.NaN; + return mSourceBounds.exactCenterY(); } } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java index e93e5444870e9..82b75408ad188 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java @@ -247,4 +247,21 @@ public class AccessibilityServiceConnectionTest { verify(mMockServiceClient).onPerformGestureResult(0, false); } + @Test + public void unbind_resetAllMagnification() { + mConnection.unbindLocked(); + verify(mMockMagnificationProcessor).resetAllIfNeeded(anyInt()); + } + + @Test + public void binderDied_resetAllMagnification() { + setServiceBinding(COMPONENT_NAME); + mConnection.bindLocked(); + mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder); + + mConnection.binderDied(); + + verify(mMockMagnificationProcessor).resetAllIfNeeded(anyInt()); + } + } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java index 621507e2bfc8d..99d6c2af6f75c 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationProcessorTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verify; @@ -235,7 +236,17 @@ public class MagnificationProcessorTest { mMagnificationProcessor.resetCurrentMagnification(TEST_DISPLAY, /* animate= */false); - verify(mMockWindowMagnificationManager).reset(TEST_DISPLAY); + verify(mMockWindowMagnificationManager).disableWindowMagnification(TEST_DISPLAY, false, + null); + } + + @Test + public void resetAllIfNeeded_resetFullscreenAndWindowMagnificationByConnectionId() { + final int connectionId = 1; + mMagnificationProcessor.resetAllIfNeeded(connectionId); + + verify(mMockFullScreenMagnificationController).resetAllIfNeeded(eq(connectionId)); + verify(mMockWindowMagnificationManager).resetAllIfNeeded(eq(connectionId)); } @Test @@ -322,7 +333,7 @@ public class MagnificationProcessorTest { final MagnificationConfig result = mMagnificationProcessor.getMagnificationConfig( TEST_DISPLAY); verify(mMockMagnificationController).transitionMagnificationConfigMode(eq(TEST_DISPLAY), - eq(newConfig), anyBoolean()); + eq(newConfig), anyBoolean(), anyInt()); assertConfigEquals(newConfig, result); } @@ -438,7 +449,7 @@ public class MagnificationProcessorTest { anyFloat(), anyFloat(), anyFloat()); doAnswer(enableWindowMagnificationStubAnswer).when( mWindowMagnificationManager).enableWindowMagnification(eq(TEST_DISPLAY), - anyFloat(), anyFloat(), anyFloat(), any()); + anyFloat(), anyFloat(), anyFloat(), any(), anyInt()); } public void resetAndStubMethods() { diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java index 08421de3183a2..c9ae11a14ed30 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java @@ -293,7 +293,7 @@ public class MagnificationControllerTest { // Enable window magnification while animating. mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE, - Float.NaN, Float.NaN, null); + Float.NaN, Float.NaN, null, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); @@ -310,7 +310,7 @@ public class MagnificationControllerTest { mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, obtainMagnificationConfig(MODE_WINDOW), - false); + false, TEST_SERVICE_ID); verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), eq(false)); mMockConnection.invokeCallbacks(); @@ -325,13 +325,13 @@ public class MagnificationControllerTest { activateMagnifier(MODE_WINDOW, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y); mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, obtainMagnificationConfig(MODE_FULLSCREEN), - animate); + animate, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, - animate, MAGNIFICATION_GESTURE_HANDLER_ID); + animate, TEST_SERVICE_ID); } @Test @@ -345,7 +345,7 @@ public class MagnificationControllerTest { // Config-setting mode mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, obtainMagnificationConfig(MODE_FULLSCREEN), - true); + true, TEST_SERVICE_ID); assertEquals(DEFAULT_SCALE, mScreenMagnificationController.getScale(TEST_DISPLAY), 0); assertEquals(MAGNIFIED_CENTER_X, mScreenMagnificationController.getCenterX(TEST_DISPLAY), @@ -365,7 +365,7 @@ public class MagnificationControllerTest { // Config-setting mode mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, obtainMagnificationConfig(MODE_FULLSCREEN), - true); + true, TEST_SERVICE_ID); verify(mTransitionCallBack, never()).onResult(TEST_DISPLAY, true); } @@ -772,7 +772,7 @@ public class MagnificationControllerTest { centerY, true, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID); } else { mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE, - centerX, centerY, null); + centerX, centerY, null, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); } } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java index 0659a60193365..4c03ec34f0742 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java @@ -35,6 +35,9 @@ import android.view.accessibility.IRemoteMagnificationAnimationCallback; import android.view.accessibility.IWindowMagnificationConnection; import android.view.accessibility.IWindowMagnificationConnectionCallback; +import java.util.ArrayList; +import java.util.List; + /** * Mocks the basic logic of window magnification in System UI. We assume the screen size is * unlimited, so source bounds is always on the center of the mirror window bounds. @@ -42,6 +45,8 @@ import android.view.accessibility.IWindowMagnificationConnectionCallback; class MockWindowMagnificationConnection { public static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY; + public static final int TEST_DISPLAY_2 = Display.DEFAULT_DISPLAY + 1; + private final List mValidDisplayIds; private final IWindowMagnificationConnection mConnection; private final Binder mBinder; private final boolean mSuspendCallback; @@ -60,6 +65,10 @@ class MockWindowMagnificationConnection { } MockWindowMagnificationConnection(boolean suspendCallback) throws RemoteException { + mValidDisplayIds = new ArrayList(); + mValidDisplayIds.add(TEST_DISPLAY); + mValidDisplayIds.add(TEST_DISPLAY_2); + mSuspendCallback = suspendCallback; mConnection = mock(IWindowMagnificationConnection.class); mBinder = mock(Binder.class); @@ -86,8 +95,8 @@ class MockWindowMagnificationConnection { private void stubEnableWindowMagnification() throws RemoteException { doAnswer((invocation) -> { final int displayId = invocation.getArgument(0); - if (displayId != TEST_DISPLAY) { - throw new IllegalArgumentException("only support default display :" + displayId); + if (!mValidDisplayIds.contains(displayId)) { + throw new IllegalArgumentException("Not support display :" + displayId); } mWindowMagnificationEnabled = true; final float scale = invocation.getArgument(1); @@ -107,8 +116,8 @@ class MockWindowMagnificationConnection { private void stubDisableWindowMagnification() throws RemoteException { doAnswer((invocation) -> { final int displayId = invocation.getArgument(0); - if (displayId != TEST_DISPLAY) { - throw new IllegalArgumentException("only support default display :" + displayId); + if (!mValidDisplayIds.contains(displayId)) { + throw new IllegalArgumentException("Not support display :" + displayId); } setAnimationCallback(invocation.getArgument(1)); mHasPendingCallback = true; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java index 85512f36da41d..8b7a19136f50f 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java @@ -16,6 +16,9 @@ package com.android.server.accessibility.magnification; +import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY; +import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY_2; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; @@ -38,13 +41,13 @@ import android.content.Intent; import android.content.IntentFilter; import android.graphics.PointF; import android.graphics.Rect; +import android.graphics.Region; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.test.mock.MockContentResolver; -import android.view.Display; import android.view.InputDevice; import android.view.MotionEvent; import android.view.accessibility.IRemoteMagnificationAnimationCallback; @@ -67,8 +70,8 @@ import org.mockito.invocation.InvocationOnMock; */ public class WindowMagnificationManagerTest { - private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY; private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM; + private static final int SERVICE_ID = 1; private MockWindowMagnificationConnection mMockConnection; @Mock @@ -185,7 +188,7 @@ public class WindowMagnificationManagerTest { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f, - mAnimationCallback); + mAnimationCallback, SERVICE_ID); verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(2f), eq(200f), eq(300f), eq(0f), eq(0f), @@ -377,14 +380,51 @@ public class WindowMagnificationManagerTest { } @Test - public void resetMagnification_enabled_windowMagnifierDisabled() { + public void requestConnectionToNull_expectedGetterResults() { mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); - mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN); - assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1); - mWindowMagnificationManager.reset(TEST_DISPLAY); + mWindowMagnificationManager.requestConnection(false); + + assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0); + assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY))); + assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY))); + final Region bounds = new Region(); + mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds); + assertTrue(bounds.isEmpty()); + } + + @Test + public void resetAllMagnification_enabledBySameId_windowMagnifiersDisabled() { + mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f, + 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); + assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); + + mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID); assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); + } + + @Test + public void resetAllMagnification_enabledByDifferentId_windowMagnifierDisabled() { + final int serviceId2 = SERVICE_ID + 1; + mWindowMagnificationManager.setConnection(mMockConnection.getConnection()); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, SERVICE_ID); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY_2, 3f, + 100f, 200f, null, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER, serviceId2); + assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); + + mWindowMagnificationManager.resetAllIfNeeded(SERVICE_ID); + + assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY)); + assertTrue(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY_2)); } @Test @@ -438,6 +478,22 @@ public class WindowMagnificationManagerTest { eq(100f), eq(200f), eq(-1f), eq(-1f), notNull()); } + @Test + public void magnifierGetters_disabled_expectedValues() { + mWindowMagnificationManager.requestConnection(true); + mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, + 100f, 200f, WindowMagnificationManager.WINDOW_POSITION_AT_CENTER); + + mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false); + + assertEquals(1f, mWindowMagnificationManager.getScale(TEST_DISPLAY), 0); + assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterX(TEST_DISPLAY))); + assertTrue(Float.isNaN(mWindowMagnificationManager.getCenterY(TEST_DISPLAY))); + final Region bounds = new Region(); + mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, bounds); + assertTrue(bounds.isEmpty()); + } + @Test public void onDisplayRemoved_enabledOnTestDisplay_disabled() { mWindowMagnificationManager.requestConnection(true);