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 878ebc5bbfbde..80408518d84e8 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -53,10 +53,13 @@ import com.android.server.accessibility.AccessibilityManagerService;
* is triggered.
*
4. {@link #onTripleTapped} updates magnification switch UI depending on magnification
* capabilities and magnification active state when triple-tap gesture is detected.
+ * 4. {@link #onRequestMagnificationSpec} updates magnification switch UI depending on
+ * magnification capabilities and magnification active state when new magnification spec is
+ * changed by external request from calling public APIs.
*
*
- * Note Updates magnification switch UI when magnification mode transition
- * is done {@link DisableMagnificationCallback#onResult}.
+ * Note Updates magnification switch UI when magnification mode transition
+ * is done and before invoking {@link TransitionCallBack#onResult}.
*/
public class MagnificationController implements WindowMagnificationManager.Callback,
MagnificationGestureHandler.Callback,
@@ -205,21 +208,22 @@ public class MagnificationController implements WindowMagnificationManager.Callb
@Override
public void onRequestMagnificationSpec(int displayId, int serviceId) {
+ final WindowMagnificationManager windowMagnificationManager;
synchronized (mLock) {
if (serviceId == AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID) {
return;
}
- if (mWindowMagnificationMgr == null
- || !mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId)) {
- return;
- }
+ updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+ windowMagnificationManager = mWindowMagnificationMgr;
+ }
+ if (windowMagnificationManager != null) {
mWindowMagnificationMgr.disableWindowMagnification(displayId, false);
}
}
// TODO : supporting multi-display (b/182227245).
@Override
- public void onWindowMagnificationActivationState(boolean activated) {
+ public void onWindowMagnificationActivationState(int displayId, boolean activated) {
if (activated) {
mWindowModeEnabledTime = SystemClock.uptimeMillis();
@@ -227,6 +231,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
}
logMagnificationModeWithImeOnIfNeeded();
+ disableFullScreenMagnificationIfNeeded(displayId);
} else {
logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
SystemClock.uptimeMillis() - mWindowModeEnabledTime);
@@ -237,6 +242,17 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
}
+ private void disableFullScreenMagnificationIfNeeded(int displayId) {
+ final FullScreenMagnificationController fullScreenMagnificationController =
+ getFullScreenMagnificationController();
+ // Internal request may be for transition, so we just need to check external request.
+ final boolean isMagnifyByExternalRequest =
+ fullScreenMagnificationController.getIdOfLastServiceToMagnify(displayId) > 0;
+ if (isMagnifyByExternalRequest) {
+ fullScreenMagnificationController.reset(displayId, false);
+ }
+ }
+
@Override
public void onFullScreenMagnificationActivationState(boolean activated) {
if (activated) {
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 ded601e70ff12..86f61eef2e7a6 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -97,9 +97,10 @@ public class WindowMagnificationManager implements
/**
* Called when the state of the magnification activation is changed.
*
+ * @param displayId The logical display id.
* @param activated {@code true} if the magnification is activated, otherwise {@code false}.
*/
- void onWindowMagnificationActivationState(boolean activated);
+ void onWindowMagnificationActivationState(int displayId, boolean activated);
}
private final Callback mCallback;
@@ -285,7 +286,7 @@ public class WindowMagnificationManager implements
}
if (enabled) {
- mCallback.onWindowMagnificationActivationState(true);
+ mCallback.onWindowMagnificationActivationState(displayId, true);
}
}
@@ -321,7 +322,7 @@ public class WindowMagnificationManager implements
}
if (disabled) {
- mCallback.onWindowMagnificationActivationState(false);
+ mCallback.onWindowMagnificationActivationState(displayId, false);
}
}
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 3dff36e8f379d..81be2e7d8cea6 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
@@ -64,6 +64,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
/**
* Tests for MagnificationController.
@@ -72,6 +73,7 @@ import org.mockito.MockitoAnnotations;
public class MagnificationControllerTest {
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
+ private static final int TEST_SERVICE_ID = 1;
private static final Region MAGNIFICATION_REGION = new Region(0, 0, 500, 600);
private static final float MAGNIFIED_CENTER_X = 100;
private static final float MAGNIFIED_CENTER_Y = 200;
@@ -96,6 +98,7 @@ public class MagnificationControllerTest {
private WindowMagnificationManager mWindowMagnificationManager;
private MockContentResolver mMockResolver;
private MagnificationController mMagnificationController;
+ private FullScreenMagnificationControllerStubber mScreenMagnificationControllerStubber;
@Before
public void setUp() throws Exception {
@@ -112,8 +115,11 @@ public class MagnificationControllerTest {
mock(WindowMagnificationManager.Callback.class)));
mMockConnection = new MockWindowMagnificationConnection(true);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+ mScreenMagnificationControllerStubber = new FullScreenMagnificationControllerStubber(
+ mScreenMagnificationController);
mMagnificationController = spy(new MagnificationController(mService, new Object(), mContext,
mScreenMagnificationController, mWindowMagnificationManager));
+
mMagnificationController.setMagnificationCapabilities(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
}
@@ -240,9 +246,11 @@ public class MagnificationControllerTest {
MODE_FULLSCREEN,
mTransitionCallBack);
- verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY,
- DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
- true, MAGNIFICATION_GESTURE_HANDLER_ID);
+ assertEquals(DEFAULT_SCALE, mScreenMagnificationController.getScale(TEST_DISPLAY), 0);
+ assertEquals(MAGNIFIED_CENTER_X, mScreenMagnificationController.getCenterX(TEST_DISPLAY),
+ 0);
+ assertEquals(MAGNIFIED_CENTER_Y, mScreenMagnificationController.getCenterY(TEST_DISPLAY),
+ 0);
verify(mTransitionCallBack).onResult(true);
}
@@ -286,12 +294,31 @@ public class MagnificationControllerTest {
public void onMagnificationRequest_windowMagnifying_disableWindow() throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
- mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, 1);
+ mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID);
mMockConnection.invokeCallbacks();
assertFalse(mWindowMagnificationManager.isWindowMagnifierEnabled(TEST_DISPLAY));
}
+ @Test
+ public void magnifyThroughExternalRequest_showMagnificationButton() {
+ mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE,
+ MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, false, TEST_SERVICE_ID);
+ mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID);
+
+ verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ eq(MODE_FULLSCREEN));
+ }
+
+ @Test
+ public void setScaleOneThroughExternalRequest_removeMagnificationButton() {
+ mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, 1.0f,
+ MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, false, TEST_SERVICE_ID);
+ mMagnificationController.onRequestMagnificationSpec(TEST_DISPLAY, TEST_SERVICE_ID);
+
+ verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
+ }
+
@Test
public void onPerformScaleAction_magnifierEnabled_handleScaleChange() throws RemoteException {
final float newScale = 4.0f;
@@ -305,14 +332,25 @@ public class MagnificationControllerTest {
@Test
public void onWindowMagnificationActivationState_windowActivated_logWindowDuration() {
- mMagnificationController.onWindowMagnificationActivationState(true);
+ mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
- mMagnificationController.onWindowMagnificationActivationState(false);
+ mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, false);
verify(mMagnificationController).logMagnificationUsageState(
eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW), anyLong());
}
+ @Test
+ public void onWinodwModeActivated_fullScreenIsActivatedByExternal_fullScreenIsDisabled() {
+ mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY,
+ DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
+ true, TEST_SERVICE_ID);
+
+ mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
+
+ assertFalse(mScreenMagnificationController.isMagnifying(TEST_DISPLAY));
+ }
+
@Test
public void
onFullScreenMagnificationActivationState_fullScreenActivated_logFullScreenDuration() {
@@ -417,6 +455,18 @@ public class MagnificationControllerTest {
eq(MODE_FULLSCREEN));
}
+ @Test
+ public void triggerShortcutToShowMagnificationBound_fullscreenMode_showMagnificationButton() {
+ setMagnificationModeSettings(MODE_FULLSCREEN);
+
+ when(mScreenMagnificationController.isForceShowMagnifiableBounds(TEST_DISPLAY)).thenReturn(
+ true);
+ mMagnificationController.onShortcutTriggered(TEST_DISPLAY, MODE_FULLSCREEN);
+
+ verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
+ eq(MODE_FULLSCREEN));
+ }
+
@Test
public void onShortcutTriggered_windowModeDisabled_removeMagnificationButton()
throws RemoteException {
@@ -488,7 +538,7 @@ public class MagnificationControllerTest {
@Test
public void imeWindowStateShown_windowMagnifying_logWindowMode() {
- mMagnificationController.onWindowMagnificationActivationState(true);
+ mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
mMagnificationController.onImeWindowVisibilityChanged(true);
@@ -522,26 +572,19 @@ public class MagnificationControllerTest {
@Test
public void imeWindowStateHidden_fullScreenMagnifying_noLogAnyMode() {
- mMagnificationController.onWindowMagnificationActivationState(true);
+ mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
}
private void setMagnificationEnabled(int mode) throws RemoteException {
-
setMagnificationEnabled(mode, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y);
}
private void setMagnificationEnabled(int mode, float centerX, float centerY)
throws RemoteException {
setMagnificationModeSettings(mode);
- Mockito.reset(mScreenMagnificationController);
- doAnswer(invocation -> {
- final Region outRegion = invocation.getArgument(1);
- outRegion.set(MAGNIFICATION_REGION);
- return null;
- }).when(mScreenMagnificationController).getMagnificationRegion(anyInt(), any(Region.class));
-
+ mScreenMagnificationControllerStubber.resetAndStubMethods();
final boolean windowMagnifying = mWindowMagnificationManager.isWindowMagnifierEnabled(
TEST_DISPLAY);
if (windowMagnifying) {
@@ -549,21 +592,9 @@ public class MagnificationControllerTest {
mMockConnection.invokeCallbacks();
}
if (mode == MODE_FULLSCREEN) {
- when(mScreenMagnificationController.isMagnifying(TEST_DISPLAY)).thenReturn(true);
- when(mScreenMagnificationController.isForceShowMagnifiableBounds(
- TEST_DISPLAY)).thenReturn(true);
- when(mScreenMagnificationController.getPersistedScale()).thenReturn(DEFAULT_SCALE);
- when(mScreenMagnificationController.getScale(TEST_DISPLAY)).thenReturn(DEFAULT_SCALE);
- when(mScreenMagnificationController.getCenterX(TEST_DISPLAY)).thenReturn(
- centerX);
- when(mScreenMagnificationController.getCenterY(TEST_DISPLAY)).thenReturn(
- centerY);
+ mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE, centerX,
+ centerY, true, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
} else {
- doAnswer(invocation -> {
- when(mScreenMagnificationController.isMagnifying(TEST_DISPLAY)).thenReturn(true);
- return null;
- }).when(mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY),
- eq(DEFAULT_SCALE), anyFloat(), anyFloat(), anyBoolean(), anyInt());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, DEFAULT_SCALE,
centerX, centerY, null);
mMockConnection.invokeCallbacks();
@@ -574,4 +605,90 @@ public class MagnificationControllerTest {
Settings.Secure.putIntForUser(mMockResolver,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, mode, CURRENT_USER_ID);
}
+
+ /**
+ * Stubs public methods to simulate the real beahviours.
+ */
+ private static class FullScreenMagnificationControllerStubber {
+ private final FullScreenMagnificationController mScreenMagnificationController;
+ private boolean mIsMagnifying = false;
+ private float mScale = 1.0f;
+ private float mCenterX = 0;
+ private float mCenterY = 0;
+ private int mServiceId = -1;
+
+ FullScreenMagnificationControllerStubber(
+ FullScreenMagnificationController screenMagnificationController) {
+ mScreenMagnificationController = screenMagnificationController;
+ resetCenter();
+ stubMethods();
+ }
+
+ private void stubMethods() {
+ doAnswer(invocation -> mIsMagnifying).when(mScreenMagnificationController).isMagnifying(
+ TEST_DISPLAY);
+ doAnswer(invocation -> mIsMagnifying).when(
+ mScreenMagnificationController).isForceShowMagnifiableBounds(TEST_DISPLAY);
+ doAnswer(invocation -> mScale).when(mScreenMagnificationController).getPersistedScale();
+ doAnswer(invocation -> mScale).when(mScreenMagnificationController).getScale(
+ TEST_DISPLAY);
+ doAnswer(invocation -> mCenterX).when(mScreenMagnificationController).getCenterX(
+ TEST_DISPLAY);
+ doAnswer(invocation -> mCenterY).when(mScreenMagnificationController).getCenterY(
+ TEST_DISPLAY);
+ doAnswer(invocation -> mServiceId).when(
+ mScreenMagnificationController).getIdOfLastServiceToMagnify(TEST_DISPLAY);
+
+ doAnswer(invocation -> {
+ final Region outRegion = invocation.getArgument(1);
+ outRegion.set(MAGNIFICATION_REGION);
+ return null;
+ }).when(mScreenMagnificationController).getMagnificationRegion(anyInt(),
+ any(Region.class));
+
+ Answer setScaleAndCenterStubAnswer = invocation -> {
+ final float scale = invocation.getArgument(1);
+ mScale = Float.isNaN(scale) ? mScale : scale;
+ mIsMagnifying = mScale > 1.0f;
+ if (mIsMagnifying) {
+ mCenterX = invocation.getArgument(2);
+ mCenterY = invocation.getArgument(3);
+ mServiceId = invocation.getArgument(5);
+ } else {
+ mServiceId = -1;
+ resetCenter();
+ }
+ return true;
+ };
+ doAnswer(setScaleAndCenterStubAnswer).when(
+ mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY),
+ anyFloat(), anyFloat(), anyFloat(), any(), anyInt());
+
+ doAnswer(setScaleAndCenterStubAnswer).when(
+ mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY),
+ anyFloat(), anyFloat(), anyFloat(), anyBoolean(), anyInt());
+
+ Answer resetStubAnswer = invocation -> {
+ mScale = 1.0f;
+ mIsMagnifying = false;
+ mServiceId = -1;
+ resetCenter();
+ return true;
+ };
+ doAnswer(resetStubAnswer).when(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
+ any());
+ doAnswer(resetStubAnswer).when(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
+ anyBoolean());
+ }
+
+ private void resetCenter() {
+ mCenterX = MAGNIFICATION_REGION.getBounds().exactCenterX();
+ mCenterY = MAGNIFICATION_REGION.getBounds().exactCenterY();
+ }
+
+ public void resetAndStubMethods() {
+ Mockito.reset(mScreenMagnificationController);
+ stubMethods();
+ }
+ }
}
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 955217c7d93f8..ffa0185b45420 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
@@ -397,7 +397,7 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
- verify(mMockCallback).onWindowMagnificationActivationState(eq(true));
+ verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, true);
}
@Test
@@ -406,7 +406,7 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, true);
- verify(mMockCallback).onWindowMagnificationActivationState(eq(false));
+ verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, false);
}
private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {