Loading packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +2 −0 Original line number Diff line number Diff line Loading @@ -353,6 +353,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold mSourceBounds.setEmpty(); updateSystemUIStateIfNeeded(); mContext.unregisterComponentCallbacks(this); // Notify source bounds empty when magnification is deleted. mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId, new Rect()); } @Override Loading packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -292,6 +292,22 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { assertFalse(hasMagnificationOverlapFlag()); } @Test public void deleteWindowMagnification_notifySourceBoundsChanged() { mInstrumentation.runOnMainSync( () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN)); mInstrumentation.runOnMainSync( () -> mWindowMagnificationController.deleteWindowMagnification()); // The first time is for notifying magnification enabled and the second time is for // notifying magnification disabled. verify(mWindowMagnifierCallback, times(2)).onSourceBoundsChanged( (eq(mContext.getDisplayId())), any()); } @Test public void moveMagnifier_schedulesFrame() { mInstrumentation.runOnMainSync(() -> { Loading services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +9 −8 Original line number Diff line number Diff line Loading @@ -356,13 +356,6 @@ public class FullScreenMagnificationController implements mSpecAnimationBridge, spec, animationCallback); mControllerCtx.getHandler().sendMessage(m); } final boolean lastMagnificationActivated = mMagnificationActivated; mMagnificationActivated = spec.scale > 1.0f; if (mMagnificationActivated != lastMagnificationActivated) { mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState( mDisplayId, mMagnificationActivated); } } /** Loading @@ -376,9 +369,17 @@ public class FullScreenMagnificationController implements @GuardedBy("mLock") void onMagnificationChangedLocked() { final float scale = getScale(); final boolean lastMagnificationActivated = mMagnificationActivated; mMagnificationActivated = scale > 1.0f; if (mMagnificationActivated != lastMagnificationActivated) { mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState( mDisplayId, mMagnificationActivated); } final MagnificationConfig config = new MagnificationConfig.Builder() .setMode(MAGNIFICATION_MODE_FULLSCREEN) .setScale(getScale()) .setScale(scale) .setCenterX(getCenterX()) .setCenterY(getCenterY()).build(); mMagnificationInfoChangedCallback.onFullScreenMagnificationChanged(mDisplayId, Loading services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +122 −20 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.accessibility.magnification; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW; import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION; import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL; Loading Loading @@ -111,6 +112,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb @GuardedBy("mLock") private final SparseLongArray mFullScreenModeEnabledTimeArray = new SparseLongArray(); /** * The transitioning magnification modes on the displays. The controller notifies * magnification change depending on the target config mode. * If the target mode is null, it means the config mode of the display is not * transitioning. */ @GuardedBy("mLock") private final SparseArray<Integer> mTransitionModes = new SparseArray(); @GuardedBy("mLock") private final SparseArray<WindowManagerInternal.AccessibilityControllerInternal .UiChangesForAccessibilityCallbacks> mAccessibilityCallbacksDelegateArray = Loading Loading @@ -213,6 +223,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb final PointF currentCenter = getCurrentMagnificationCenterLocked(displayId, targetMode); final DisableMagnificationCallback animationCallback = getDisableMagnificationEndRunnableLocked(displayId); if (currentCenter == null && animationCallback == null) { transitionCallBack.onResult(displayId, true); return; Loading @@ -233,6 +244,9 @@ public class MagnificationController implements WindowMagnificationManager.Callb transitionCallBack.onResult(displayId, true); return; } setTransitionState(displayId, targetMode); final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr(); Loading Loading @@ -286,19 +300,21 @@ public class MagnificationController implements WindowMagnificationManager.Callb Slog.w(TAG, "Discard previous animation request"); animationCallback.setExpiredAndRemoveFromListLocked(); } final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr(); final float targetScale = Float.isNaN(config.getScale()) ? getTargetModeScaleFromCurrentMagnification(displayId, targetMode) : config.getScale(); if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { try { setTransitionState(displayId, targetMode); if (targetMode == MAGNIFICATION_MODE_WINDOW) { screenMagnificationController.reset(displayId, false); windowMagnificationMgr.enableWindowMagnification(displayId, targetScale, magnificationCenter.x, magnificationCenter.y, animate ? STUB_ANIMATION_CALLBACK : null, id); } else if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) { } else if (targetMode == MAGNIFICATION_MODE_FULLSCREEN) { windowMagnificationMgr.disableWindowMagnification(displayId, false, null); if (!screenMagnificationController.isRegistered(displayId)) { screenMagnificationController.register(displayId); Loading @@ -307,6 +323,29 @@ public class MagnificationController implements WindowMagnificationManager.Callb magnificationCenter.x, magnificationCenter.y, animate, id); } } finally { // Reset transition state after enabling target mode. setTransitionState(displayId, null); } } } /** * Sets magnification config mode transition state. Called when the mode transition starts and * ends. If the targetMode and the display id are null, it resets all * the transition state. * * @param displayId The logical display id * @param targetMode The transition target mode. It is not transitioning, if the target mode * is set null */ private void setTransitionState(Integer displayId, Integer targetMode) { synchronized (mLock) { if (targetMode == null && displayId == null) { mTransitionModes.clear(); } else { mTransitionModes.put(displayId, targetMode); } } } Loading Loading @@ -413,6 +452,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb @Override public void onSourceBoundsChanged(int displayId, Rect bounds) { if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_WINDOW)) { final MagnificationConfig config = new MagnificationConfig.Builder() .setMode(MAGNIFICATION_MODE_WINDOW) .setScale(getWindowMagnificationMgr().getScale(displayId)) Loading @@ -420,12 +460,50 @@ public class MagnificationController implements WindowMagnificationManager.Callb .setCenterY(bounds.exactCenterY()).build(); mAms.notifyMagnificationChanged(displayId, new Region(bounds), config); } } @Override public void onFullScreenMagnificationChanged(int displayId, @NonNull Region region, @NonNull MagnificationConfig config) { if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_FULLSCREEN)) { mAms.notifyMagnificationChanged(displayId, region, config); } } /** * Should notify magnification change for the given display under the conditions below * * <ol> * <li> 1. No mode transitioning and the change mode is active. </li> * <li> 2. No mode transitioning and all the modes are inactive. </li> * <li> 3. It is mode transitioning and the change mode is the transition mode. </li> * </ol> * * @param displayId The logical display id * @param changeMode The mode that has magnification spec change */ private boolean shouldNotifyMagnificationChange(int displayId, int changeMode) { synchronized (mLock) { final boolean fullScreenMagnifying = mFullScreenMagnificationController != null && mFullScreenMagnificationController.isMagnifying(displayId); final boolean windowEnabled = mWindowMagnificationMgr != null && mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId); final Integer transitionMode = mTransitionModes.get(displayId); if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenMagnifying) || (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled)) && (transitionMode == null)) { return true; } if ((!fullScreenMagnifying && !windowEnabled) && (transitionMode == null)) { return true; } if (transitionMode != null && changeMode == transitionMode) { return true; } } return false; } private void disableFullScreenMagnificationIfNeeded(int displayId) { final FullScreenMagnificationController fullScreenMagnificationController = Loading Loading @@ -740,9 +818,32 @@ public class MagnificationController implements WindowMagnificationManager.Callb return; } setExpiredAndRemoveFromListLocked(); setTransitionState(mDisplayId, null); if (success) { adjustCurrentCenterIfNeededLocked(); applyMagnificationModeLocked(mTargetMode); } else { // Notify magnification change if magnification is inactive when the // transition is failed. This is for the failed transition from // full-screen to window mode. Disable magnification callback helps to send // magnification inactive change since FullScreenMagnificationController // would not notify magnification change if the spec is not changed. final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); if (mCurrentMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN && !screenMagnificationController.isMagnifying(mDisplayId)) { MagnificationConfig.Builder configBuilder = new MagnificationConfig.Builder(); Region region = new Region(); configBuilder.setMode(MAGNIFICATION_MODE_FULLSCREEN) .setScale(screenMagnificationController.getScale(mDisplayId)) .setCenterX(screenMagnificationController.getCenterX(mDisplayId)) .setCenterY(screenMagnificationController.getCenterY(mDisplayId)); screenMagnificationController.getMagnificationRegion(mDisplayId, region); mAms.notifyMagnificationChanged(mDisplayId, region, configBuilder.build()); } } updateMagnificationButton(mDisplayId, mTargetMode); if (mTransitionCallBack != null) { Loading Loading @@ -770,6 +871,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb return; } setExpiredAndRemoveFromListLocked(); setTransitionState(mDisplayId, null); applyMagnificationModeLocked(mCurrentMode); updateMagnificationButton(mDisplayId, mCurrentMode); if (mTransitionCallBack != null) { Loading services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +115 −5 Original line number Diff line number Diff line Loading @@ -197,6 +197,31 @@ public class MagnificationControllerTest { assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0); } @Test public void transitionToWindowModeFailedByReset_fullScreenMagnifying_notifyTransitionFailed() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY, MODE_WINDOW, mTransitionCallBack); verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), mCallbackArgumentCaptor.capture()); // The transition is interrupted and failed by calling reset. mCallbackArgumentCaptor.getValue().onResult(false); verify(mTransitionCallBack).onResult(TEST_DISPLAY, false); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying full-screen enabled and the second time is for notifying // the target mode transitions failed. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(MODE_FULLSCREEN, actualConfig.getMode(), 0); assertEquals(1.0f, actualConfig.getScale(), 0); } @Test public void transitionToWindowMode_disablingWindowMode_enablingWindowWithFormerCenter() throws RemoteException { Loading Loading @@ -478,6 +503,92 @@ public class MagnificationControllerTest { assertEquals(config.getScale(), actualConfig.getScale(), 0); } @Test public void transitionMagnificationMode_windowEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY, MODE_FULLSCREEN, mTransitionCallBack); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying window enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(MODE_FULLSCREEN, actualConfig.getMode(), 0); } @Test public void transitionConfigMode_windowEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); final MagnificationConfig config = obtainMagnificationConfig(MODE_FULLSCREEN); mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, config, true, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying window enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(config.getCenterX(), actualConfig.getCenterX(), 0); assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0); assertEquals(config.getScale(), actualConfig.getScale(), 0); } @Test public void transitionMagnificationMode_fullScreenEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY, MODE_WINDOW, mTransitionCallBack); verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), mCallbackArgumentCaptor.capture()); mCallbackArgumentCaptor.getValue().onResult(true); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying full-screen enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(MODE_WINDOW, actualConfig.getMode(), 0); } @Test public void transitionConfigMode_fullScreenEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); final MagnificationConfig config = obtainMagnificationConfig(MODE_WINDOW); mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, config, true, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying full-screen enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(config.getCenterX(), actualConfig.getCenterX(), 0); assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0); assertEquals(config.getScale(), actualConfig.getScale(), 0); } @Test public void onAccessibilityActionPerformed_magnifierEnabled_showMagnificationButton() throws RemoteException { Loading Loading @@ -743,7 +854,7 @@ public class MagnificationControllerTest { } @Test public void disableWindowMode_windowModeInActive_removeMagnificationButton() public void disableWindowMode_windowEnabled_removeMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); Loading @@ -753,7 +864,7 @@ public class MagnificationControllerTest { } @Test public void onFullScreenDeactivated_fullscreenModeInActive_removeMagnificationButton() public void onFullScreenDeactivated_fullScreenEnabled_removeMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, Loading @@ -766,7 +877,7 @@ public class MagnificationControllerTest { } @Test public void transitionToFullScreenMode_fullscreenModeInActive_showMagnificationButton() public void transitionToFullScreenMode_windowEnabled_showMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); Loading @@ -779,7 +890,7 @@ public class MagnificationControllerTest { } @Test public void transitionToWindow_fullscreenModeInActive_showMagnificationButton() public void transitionToWindow_fullScreenEnabled_showMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); Loading Loading @@ -1018,7 +1129,6 @@ public class MagnificationControllerTest { reset(); } final MagnificationConfig config = new MagnificationConfig.Builder().setMode( MODE_FULLSCREEN).setScale(mScale).setCenterX(mCenterX).setCenterY( mCenterY).build(); Loading Loading
packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java +2 −0 Original line number Diff line number Diff line Loading @@ -353,6 +353,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold mSourceBounds.setEmpty(); updateSystemUIStateIfNeeded(); mContext.unregisterComponentCallbacks(this); // Notify source bounds empty when magnification is deleted. mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId, new Rect()); } @Override Loading
packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -292,6 +292,22 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { assertFalse(hasMagnificationOverlapFlag()); } @Test public void deleteWindowMagnification_notifySourceBoundsChanged() { mInstrumentation.runOnMainSync( () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN)); mInstrumentation.runOnMainSync( () -> mWindowMagnificationController.deleteWindowMagnification()); // The first time is for notifying magnification enabled and the second time is for // notifying magnification disabled. verify(mWindowMagnifierCallback, times(2)).onSourceBoundsChanged( (eq(mContext.getDisplayId())), any()); } @Test public void moveMagnifier_schedulesFrame() { mInstrumentation.runOnMainSync(() -> { Loading
services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +9 −8 Original line number Diff line number Diff line Loading @@ -356,13 +356,6 @@ public class FullScreenMagnificationController implements mSpecAnimationBridge, spec, animationCallback); mControllerCtx.getHandler().sendMessage(m); } final boolean lastMagnificationActivated = mMagnificationActivated; mMagnificationActivated = spec.scale > 1.0f; if (mMagnificationActivated != lastMagnificationActivated) { mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState( mDisplayId, mMagnificationActivated); } } /** Loading @@ -376,9 +369,17 @@ public class FullScreenMagnificationController implements @GuardedBy("mLock") void onMagnificationChangedLocked() { final float scale = getScale(); final boolean lastMagnificationActivated = mMagnificationActivated; mMagnificationActivated = scale > 1.0f; if (mMagnificationActivated != lastMagnificationActivated) { mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState( mDisplayId, mMagnificationActivated); } final MagnificationConfig config = new MagnificationConfig.Builder() .setMode(MAGNIFICATION_MODE_FULLSCREEN) .setScale(getScale()) .setScale(scale) .setCenterX(getCenterX()) .setCenterY(getCenterY()).build(); mMagnificationInfoChangedCallback.onFullScreenMagnificationChanged(mDisplayId, Loading
services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +122 −20 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.accessibility.magnification; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN; import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW; import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION; import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL; Loading Loading @@ -111,6 +112,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb @GuardedBy("mLock") private final SparseLongArray mFullScreenModeEnabledTimeArray = new SparseLongArray(); /** * The transitioning magnification modes on the displays. The controller notifies * magnification change depending on the target config mode. * If the target mode is null, it means the config mode of the display is not * transitioning. */ @GuardedBy("mLock") private final SparseArray<Integer> mTransitionModes = new SparseArray(); @GuardedBy("mLock") private final SparseArray<WindowManagerInternal.AccessibilityControllerInternal .UiChangesForAccessibilityCallbacks> mAccessibilityCallbacksDelegateArray = Loading Loading @@ -213,6 +223,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb final PointF currentCenter = getCurrentMagnificationCenterLocked(displayId, targetMode); final DisableMagnificationCallback animationCallback = getDisableMagnificationEndRunnableLocked(displayId); if (currentCenter == null && animationCallback == null) { transitionCallBack.onResult(displayId, true); return; Loading @@ -233,6 +244,9 @@ public class MagnificationController implements WindowMagnificationManager.Callb transitionCallBack.onResult(displayId, true); return; } setTransitionState(displayId, targetMode); final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr(); Loading Loading @@ -286,19 +300,21 @@ public class MagnificationController implements WindowMagnificationManager.Callb Slog.w(TAG, "Discard previous animation request"); animationCallback.setExpiredAndRemoveFromListLocked(); } final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr(); final float targetScale = Float.isNaN(config.getScale()) ? getTargetModeScaleFromCurrentMagnification(displayId, targetMode) : config.getScale(); if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) { try { setTransitionState(displayId, targetMode); if (targetMode == MAGNIFICATION_MODE_WINDOW) { screenMagnificationController.reset(displayId, false); windowMagnificationMgr.enableWindowMagnification(displayId, targetScale, magnificationCenter.x, magnificationCenter.y, animate ? STUB_ANIMATION_CALLBACK : null, id); } else if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) { } else if (targetMode == MAGNIFICATION_MODE_FULLSCREEN) { windowMagnificationMgr.disableWindowMagnification(displayId, false, null); if (!screenMagnificationController.isRegistered(displayId)) { screenMagnificationController.register(displayId); Loading @@ -307,6 +323,29 @@ public class MagnificationController implements WindowMagnificationManager.Callb magnificationCenter.x, magnificationCenter.y, animate, id); } } finally { // Reset transition state after enabling target mode. setTransitionState(displayId, null); } } } /** * Sets magnification config mode transition state. Called when the mode transition starts and * ends. If the targetMode and the display id are null, it resets all * the transition state. * * @param displayId The logical display id * @param targetMode The transition target mode. It is not transitioning, if the target mode * is set null */ private void setTransitionState(Integer displayId, Integer targetMode) { synchronized (mLock) { if (targetMode == null && displayId == null) { mTransitionModes.clear(); } else { mTransitionModes.put(displayId, targetMode); } } } Loading Loading @@ -413,6 +452,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb @Override public void onSourceBoundsChanged(int displayId, Rect bounds) { if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_WINDOW)) { final MagnificationConfig config = new MagnificationConfig.Builder() .setMode(MAGNIFICATION_MODE_WINDOW) .setScale(getWindowMagnificationMgr().getScale(displayId)) Loading @@ -420,12 +460,50 @@ public class MagnificationController implements WindowMagnificationManager.Callb .setCenterY(bounds.exactCenterY()).build(); mAms.notifyMagnificationChanged(displayId, new Region(bounds), config); } } @Override public void onFullScreenMagnificationChanged(int displayId, @NonNull Region region, @NonNull MagnificationConfig config) { if (shouldNotifyMagnificationChange(displayId, MAGNIFICATION_MODE_FULLSCREEN)) { mAms.notifyMagnificationChanged(displayId, region, config); } } /** * Should notify magnification change for the given display under the conditions below * * <ol> * <li> 1. No mode transitioning and the change mode is active. </li> * <li> 2. No mode transitioning and all the modes are inactive. </li> * <li> 3. It is mode transitioning and the change mode is the transition mode. </li> * </ol> * * @param displayId The logical display id * @param changeMode The mode that has magnification spec change */ private boolean shouldNotifyMagnificationChange(int displayId, int changeMode) { synchronized (mLock) { final boolean fullScreenMagnifying = mFullScreenMagnificationController != null && mFullScreenMagnificationController.isMagnifying(displayId); final boolean windowEnabled = mWindowMagnificationMgr != null && mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId); final Integer transitionMode = mTransitionModes.get(displayId); if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenMagnifying) || (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled)) && (transitionMode == null)) { return true; } if ((!fullScreenMagnifying && !windowEnabled) && (transitionMode == null)) { return true; } if (transitionMode != null && changeMode == transitionMode) { return true; } } return false; } private void disableFullScreenMagnificationIfNeeded(int displayId) { final FullScreenMagnificationController fullScreenMagnificationController = Loading Loading @@ -740,9 +818,32 @@ public class MagnificationController implements WindowMagnificationManager.Callb return; } setExpiredAndRemoveFromListLocked(); setTransitionState(mDisplayId, null); if (success) { adjustCurrentCenterIfNeededLocked(); applyMagnificationModeLocked(mTargetMode); } else { // Notify magnification change if magnification is inactive when the // transition is failed. This is for the failed transition from // full-screen to window mode. Disable magnification callback helps to send // magnification inactive change since FullScreenMagnificationController // would not notify magnification change if the spec is not changed. final FullScreenMagnificationController screenMagnificationController = getFullScreenMagnificationController(); if (mCurrentMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN && !screenMagnificationController.isMagnifying(mDisplayId)) { MagnificationConfig.Builder configBuilder = new MagnificationConfig.Builder(); Region region = new Region(); configBuilder.setMode(MAGNIFICATION_MODE_FULLSCREEN) .setScale(screenMagnificationController.getScale(mDisplayId)) .setCenterX(screenMagnificationController.getCenterX(mDisplayId)) .setCenterY(screenMagnificationController.getCenterY(mDisplayId)); screenMagnificationController.getMagnificationRegion(mDisplayId, region); mAms.notifyMagnificationChanged(mDisplayId, region, configBuilder.build()); } } updateMagnificationButton(mDisplayId, mTargetMode); if (mTransitionCallBack != null) { Loading Loading @@ -770,6 +871,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb return; } setExpiredAndRemoveFromListLocked(); setTransitionState(mDisplayId, null); applyMagnificationModeLocked(mCurrentMode); updateMagnificationButton(mDisplayId, mCurrentMode); if (mTransitionCallBack != null) { Loading
services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java +115 −5 Original line number Diff line number Diff line Loading @@ -197,6 +197,31 @@ public class MagnificationControllerTest { assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0); } @Test public void transitionToWindowModeFailedByReset_fullScreenMagnifying_notifyTransitionFailed() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY, MODE_WINDOW, mTransitionCallBack); verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), mCallbackArgumentCaptor.capture()); // The transition is interrupted and failed by calling reset. mCallbackArgumentCaptor.getValue().onResult(false); verify(mTransitionCallBack).onResult(TEST_DISPLAY, false); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying full-screen enabled and the second time is for notifying // the target mode transitions failed. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(MODE_FULLSCREEN, actualConfig.getMode(), 0); assertEquals(1.0f, actualConfig.getScale(), 0); } @Test public void transitionToWindowMode_disablingWindowMode_enablingWindowWithFormerCenter() throws RemoteException { Loading Loading @@ -478,6 +503,92 @@ public class MagnificationControllerTest { assertEquals(config.getScale(), actualConfig.getScale(), 0); } @Test public void transitionMagnificationMode_windowEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY, MODE_FULLSCREEN, mTransitionCallBack); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying window enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(MODE_FULLSCREEN, actualConfig.getMode(), 0); } @Test public void transitionConfigMode_windowEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); final MagnificationConfig config = obtainMagnificationConfig(MODE_FULLSCREEN); mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, config, true, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying window enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(config.getCenterX(), actualConfig.getCenterX(), 0); assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0); assertEquals(config.getScale(), actualConfig.getScale(), 0); } @Test public void transitionMagnificationMode_fullScreenEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); mMagnificationController.transitionMagnificationModeLocked(TEST_DISPLAY, MODE_WINDOW, mTransitionCallBack); verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), mCallbackArgumentCaptor.capture()); mCallbackArgumentCaptor.getValue().onResult(true); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying full-screen enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(MODE_WINDOW, actualConfig.getMode(), 0); } @Test public void transitionConfigMode_fullScreenEnabled_notifyTargetMagnificationChanged() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); final MagnificationConfig config = obtainMagnificationConfig(MODE_WINDOW); mMagnificationController.transitionMagnificationConfigMode(TEST_DISPLAY, config, true, TEST_SERVICE_ID); mMockConnection.invokeCallbacks(); final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass( MagnificationConfig.class); // The first time is for notifying full-screen enabled and the second time is for notifying // the target mode transitions. verify(mService, times(2)).notifyMagnificationChanged(eq(TEST_DISPLAY), any(Region.class), configCaptor.capture()); final MagnificationConfig actualConfig = configCaptor.getValue(); assertEquals(config.getCenterX(), actualConfig.getCenterX(), 0); assertEquals(config.getCenterY(), actualConfig.getCenterY(), 0); assertEquals(config.getScale(), actualConfig.getScale(), 0); } @Test public void onAccessibilityActionPerformed_magnifierEnabled_showMagnificationButton() throws RemoteException { Loading Loading @@ -743,7 +854,7 @@ public class MagnificationControllerTest { } @Test public void disableWindowMode_windowModeInActive_removeMagnificationButton() public void disableWindowMode_windowEnabled_removeMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); Loading @@ -753,7 +864,7 @@ public class MagnificationControllerTest { } @Test public void onFullScreenDeactivated_fullscreenModeInActive_removeMagnificationButton() public void onFullScreenDeactivated_fullScreenEnabled_removeMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, Loading @@ -766,7 +877,7 @@ public class MagnificationControllerTest { } @Test public void transitionToFullScreenMode_fullscreenModeInActive_showMagnificationButton() public void transitionToFullScreenMode_windowEnabled_showMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_WINDOW); Loading @@ -779,7 +890,7 @@ public class MagnificationControllerTest { } @Test public void transitionToWindow_fullscreenModeInActive_showMagnificationButton() public void transitionToWindow_fullScreenEnabled_showMagnificationButton() throws RemoteException { setMagnificationEnabled(MODE_FULLSCREEN); Loading Loading @@ -1018,7 +1129,6 @@ public class MagnificationControllerTest { reset(); } final MagnificationConfig config = new MagnificationConfig.Builder().setMode( MODE_FULLSCREEN).setScale(mScale).setCenterX(mCenterX).setCenterY( mCenterY).build(); Loading