Fix inconsistent scale when setting magnificaotion config

We used to use MagnificationScaleProvider to retrive the
scale when transitioning the mode, which is incorrect
because the provider only persists the scale changed by users.
If the scale is changed by public api, then the scale will
become inconsistent.

To fix it we choose the scale based on the target  mode.
We also fix that mode transition without animation should be
considered as a transition case.

We also add more log for flaky CTS debugging.

Bug: 218792845
Test: atest MagnificationProcessorTest
      atest com.android.server.accessibility.magnification
Change-Id: I47f49345ce46f726d6e06e203110ef793f35c76e
This commit is contained in:
ryanlwlin
2022-02-10 14:37:05 +08:00
parent 6cba6c1bee
commit db026034a9
6 changed files with 248 additions and 109 deletions

View File

@@ -78,6 +78,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
private static final boolean DEBUG = false;
private static final String TAG = "MagnificationController";
private final AccessibilityManagerService mAms;
private final PointF mTempPoint = new PointF();
private final Object mLock;
@@ -194,11 +195,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
*/
public void transitionMagnificationModeLocked(int displayId, int targetMode,
@NonNull TransitionCallBack transitionCallBack) {
final PointF magnificationCenter = getCurrentMagnificationBoundsCenterLocked(displayId,
targetMode);
final PointF currentCenter = getCurrentMagnificationCenterLocked(displayId, targetMode);
final DisableMagnificationCallback animationCallback =
getDisableMagnificationEndRunnableLocked(displayId);
if (magnificationCenter == null && animationCallback == null) {
if (currentCenter == null && animationCallback == null) {
transitionCallBack.onResult(displayId, true);
return;
}
@@ -213,7 +213,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
}
if (magnificationCenter == null) {
if (currentCenter == null) {
Slog.w(TAG, "Invalid center, ignore it");
transitionCallBack.onResult(displayId, true);
return;
@@ -221,10 +221,10 @@ public class MagnificationController implements WindowMagnificationManager.Callb
final FullScreenMagnificationController screenMagnificationController =
getFullScreenMagnificationController();
final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
final float scale = mScaleProvider.getScale(displayId);
final float scale = getTargetModeScaleFromCurrentMagnification(displayId, targetMode);
final DisableMagnificationCallback animationEndCallback =
new DisableMagnificationCallback(transitionCallBack, displayId, targetMode,
scale, magnificationCenter, true);
scale, currentCenter, true);
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
screenMagnificationController.reset(displayId, animationEndCallback);
} else {
@@ -247,17 +247,20 @@ public class MagnificationController implements WindowMagnificationManager.Callb
*/
public void transitionMagnificationConfigMode(int displayId, MagnificationConfig config,
boolean animate, int id) {
if (DEBUG) {
Slog.d(TAG, "transitionMagnificationConfigMode displayId = " + displayId
+ ", config = " + config);
}
synchronized (mLock) {
final int targetMode = config.getMode();
final PointF currentBoundsCenter = getCurrentMagnificationBoundsCenterLocked(displayId,
targetMode);
final PointF currentCenter = getCurrentMagnificationCenterLocked(displayId, targetMode);
final PointF magnificationCenter = new PointF(config.getCenterX(), config.getCenterY());
if (currentBoundsCenter != null) {
if (currentCenter != null) {
final float centerX = Float.isNaN(config.getCenterX())
? currentBoundsCenter.x
? currentCenter.x
: config.getCenterX();
final float centerY = Float.isNaN(config.getCenterY())
? currentBoundsCenter.y
? currentCenter.y
: config.getCenterY();
magnificationCenter.set(centerX, centerY);
}
@@ -272,24 +275,36 @@ public class MagnificationController implements WindowMagnificationManager.Callb
final FullScreenMagnificationController screenMagnificationController =
getFullScreenMagnificationController();
final WindowMagnificationManager windowMagnificationMgr = getWindowMagnificationMgr();
final float scale = mScaleProvider.getScale(displayId);
final float targetScale = Float.isNaN(config.getScale())
? getTargetModeScaleFromCurrentMagnification(displayId, targetMode)
: config.getScale();
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
screenMagnificationController.reset(displayId, false);
windowMagnificationMgr.enableWindowMagnification(displayId,
scale, magnificationCenter.x, magnificationCenter.y,
targetScale, magnificationCenter.x, magnificationCenter.y,
animate ? STUB_ANIMATION_CALLBACK : null, id);
} else if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
windowMagnificationMgr.disableWindowMagnification(displayId, false, null);
if (!screenMagnificationController.isRegistered(displayId)) {
screenMagnificationController.register(displayId);
}
screenMagnificationController.setScaleAndCenter(displayId, scale,
screenMagnificationController.setScaleAndCenter(displayId, targetScale,
magnificationCenter.x, magnificationCenter.y, animate,
id);
}
}
}
// We assume the target mode is different from the current mode, and there is only
// two modes, so we get the target scale from another mode.
private float getTargetModeScaleFromCurrentMagnification(int displayId, int targetMode) {
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
return getFullScreenMagnificationController().getScale(displayId);
} else {
return getWindowMagnificationMgr().getScale(displayId);
}
}
/**
* Return {@code true} if disable magnification animation callback of the display is running.
*
@@ -384,7 +399,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
public void onSourceBoundsChanged(int displayId, Rect bounds) {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(MAGNIFICATION_MODE_WINDOW)
.setScale(mScaleProvider.getScale(displayId))
.setScale(getWindowMagnificationMgr().getScale(displayId))
.setCenterX(bounds.exactCenterX())
.setCenterY(bounds.exactCenterY()).build();
mAms.notifyMagnificationChanged(displayId, new Region(bounds), config);
@@ -607,8 +622,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
}
}
private @Nullable
PointF getCurrentMagnificationBoundsCenterLocked(int displayId, int targetMode) {
private @Nullable PointF getCurrentMagnificationCenterLocked(int displayId, int targetMode) {
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
if (mWindowMagnificationMgr == null
|| !mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId)) {

View File

@@ -26,6 +26,7 @@ import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANI
import android.accessibilityservice.MagnificationConfig;
import android.annotation.NonNull;
import android.graphics.Region;
import android.util.Slog;
import android.view.Display;
import java.io.PrintWriter;
@@ -56,6 +57,9 @@ import java.util.ArrayList;
*/
public class MagnificationProcessor {
private static final String TAG = "MagnificationProcessor";
private static final boolean DEBUG = false;
private final MagnificationController mController;
public MagnificationProcessor(MagnificationController controller) {
@@ -103,6 +107,9 @@ public class MagnificationProcessor {
*/
public boolean setMagnificationConfig(int displayId, @NonNull MagnificationConfig config,
boolean animate, int id) {
if (DEBUG) {
Slog.d(TAG, "setMagnificationConfig config=" + config);
}
if (transitionModeIfNeeded(displayId, config, animate, id)) {
return true;
}
@@ -125,15 +132,13 @@ public class MagnificationProcessor {
}
private boolean setScaleAndCenterForFullScreenMagnification(int displayId, float scale,
float centerX, float centerY,
boolean animate, int id) {
float centerX, float centerY, boolean animate, int id) {
if (!isRegistered(displayId)) {
register(displayId);
}
return mController.getFullScreenMagnificationController().setScaleAndCenter(
displayId,
scale,
centerX, centerY, animate, id);
displayId, scale, centerX, centerY, animate, id);
}
/**
@@ -143,8 +148,12 @@ public class MagnificationProcessor {
private boolean transitionModeIfNeeded(int displayId, MagnificationConfig config,
boolean animate, int id) {
int currentMode = getControllingMode(displayId);
if (currentMode == config.getMode()
|| !mController.hasDisableMagnificationCallback(displayId)) {
if (config.getMode() == MagnificationConfig.MAGNIFICATION_MODE_DEFAULT) {
return false;
}
// Target mode is as same as current mode and is not transitioning.
if (currentMode == config.getMode() && !mController.hasDisableMagnificationCallback(
displayId)) {
return false;
}
mController.transitionMagnificationConfigMode(displayId, config, animate, id);

View File

@@ -177,6 +177,9 @@ public class WindowMagnificationManager implements
* @param connection {@link IWindowMagnificationConnection}
*/
public void setConnection(@Nullable IWindowMagnificationConnection connection) {
if (DBG) {
Slog.d(TAG, "setConnection :" + connection);
}
synchronized (mLock) {
// Reset connectionWrapper.
if (mConnectionWrapper != null) {
@@ -223,6 +226,9 @@ public class WindowMagnificationManager implements
* @return {@code true} if {@link IWindowMagnificationConnection} state is going to change.
*/
public boolean requestConnection(boolean connect) {
if (DBG) {
Slog.d(TAG, "requestConnection :" + connect);
}
synchronized (mLock) {
if (connect == isConnected()) {
return false;
@@ -485,10 +491,6 @@ public class WindowMagnificationManager implements
final boolean enabled;
boolean previousEnabled;
synchronized (mLock) {
if (mConnectionWrapper == null) {
Slog.w(TAG, "enableWindowMagnification failed: connection null");
return false;
}
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
magnifier = createWindowMagnifier(displayId);
@@ -528,10 +530,10 @@ public class WindowMagnificationManager implements
final boolean disabled;
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null || mConnectionWrapper == null) {
Slog.w(TAG, "disableWindowMagnification failed: connection " + mConnectionWrapper);
if (magnifier == null) {
return false;
}
disabled = magnifier.disableWindowMagnificationInternal(animationCallback);
if (clear) {
mWindowMagnifiers.delete(displayId);
@@ -1018,25 +1020,33 @@ public class WindowMagnificationManager implements
}
}
@GuardedBy("mLock")
private boolean enableWindowMagnificationInternal(int displayId, float scale, float centerX,
float centerY, float magnificationFrameOffsetRatioX,
float magnificationFrameOffsetRatioY,
MagnificationAnimationCallback animationCallback) {
synchronized (mLock) {
return mConnectionWrapper != null && mConnectionWrapper.enableWindowMagnification(
displayId, scale, centerX, centerY,
magnificationFrameOffsetRatioX, magnificationFrameOffsetRatioY,
animationCallback);
if (mConnectionWrapper == null) {
Slog.w(TAG, "enableWindowMagnificationInternal mConnectionWrapper is null");
return false;
}
return mConnectionWrapper.enableWindowMagnification(
displayId, scale, centerX, centerY,
magnificationFrameOffsetRatioX, magnificationFrameOffsetRatioY,
animationCallback);
}
private boolean setScaleInternal(int displayId, float scale) {
return mConnectionWrapper != null && mConnectionWrapper.setScale(displayId, scale);
}
@GuardedBy("mLock")
private boolean disableWindowMagnificationInternal(int displayId,
MagnificationAnimationCallback animationCallback) {
return mConnectionWrapper != null && mConnectionWrapper.disableWindowMagnification(
if (mConnectionWrapper == null) {
Slog.w(TAG, "mConnectionWrapper is null");
return false;
}
return mConnectionWrapper.disableWindowMagnification(
displayId, animationCallback);
}

View File

@@ -27,6 +27,7 @@ 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.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -342,9 +343,58 @@ public class MagnificationProcessorTest {
}
@Test
public void setMagnificationConfig_controllingModeChangeAndAnimating_transitionConfigMode() {
public void setWindowModeConfig_fullScreenMode_transitionConfigMode() {
final int currentActivatedMode = MAGNIFICATION_MODE_FULLSCREEN;
final MagnificationConfig oldConfig = new MagnificationConfig.Builder()
.setMode(currentActivatedMode)
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, oldConfig);
final MagnificationConfig targetConfig = new MagnificationConfig.Builder()
.setMode(MAGNIFICATION_MODE_WINDOW)
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X + 10)
.setCenterY(TEST_CENTER_Y + 10).build();
mMagnificationProcessor.setMagnificationConfig(TEST_DISPLAY, targetConfig, false,
SERVICE_ID);
verify(mMockMagnificationController).transitionMagnificationConfigMode(eq(TEST_DISPLAY),
eq(targetConfig), eq(false), eq(SERVICE_ID));
}
@Test
public void setConfigWithDefaultMode_fullScreenMode_expectedConfig() {
final MagnificationConfig oldConfig = new MagnificationConfig.Builder()
.setMode(MAGNIFICATION_MODE_FULLSCREEN)
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X)
.setCenterY(TEST_CENTER_Y).build();
setMagnificationActivated(TEST_DISPLAY, oldConfig);
final MagnificationConfig targetConfig = new MagnificationConfig.Builder()
.setScale(TEST_SCALE + 1)
.setCenterX(TEST_CENTER_X + 10)
.setCenterY(TEST_CENTER_Y + 10).build();
mMagnificationProcessor.setMagnificationConfig(TEST_DISPLAY, targetConfig, false,
SERVICE_ID);
verify(mMockMagnificationController, never()).transitionMagnificationConfigMode(
eq(TEST_DISPLAY), any(MagnificationConfig.class), eq(false), eq(SERVICE_ID));
final MagnificationConfig expectedConfig = new MagnificationConfig.Builder()
.setMode(MAGNIFICATION_MODE_FULLSCREEN)
.setScale(TEST_SCALE + 1)
.setCenterX(TEST_CENTER_X + 10)
.setCenterY(TEST_CENTER_Y + 10).build();
assertConfigEquals(expectedConfig,
mMagnificationProcessor.getMagnificationConfig(TEST_DISPLAY));
}
@Test
public void setWindowModeConfig_transitionToFullScreenModeWithAnimation_transitionConfigMode() {
final int currentActivatedMode = MAGNIFICATION_MODE_WINDOW;
final int targetMode = MAGNIFICATION_MODE_FULLSCREEN;
final int targetMode = MAGNIFICATION_MODE_WINDOW;
final MagnificationConfig oldConfig = new MagnificationConfig.Builder()
.setMode(currentActivatedMode)
.setScale(TEST_SCALE)
@@ -356,17 +406,14 @@ public class MagnificationProcessorTest {
.setScale(TEST_SCALE)
.setCenterX(TEST_CENTER_X + 10)
.setCenterY(TEST_CENTER_Y + 10).build();
// Has magnification animation running
when(mMockMagnificationController.hasDisableMagnificationCallback(TEST_DISPLAY)).thenReturn(
true);
setMagnificationActivated(TEST_DISPLAY, newConfig);
final MagnificationConfig result = mMagnificationProcessor.getMagnificationConfig(
TEST_DISPLAY);
mMagnificationProcessor.setMagnificationConfig(TEST_DISPLAY, newConfig, false, SERVICE_ID);
verify(mMockMagnificationController).transitionMagnificationConfigMode(eq(TEST_DISPLAY),
eq(newConfig), anyBoolean(), anyInt());
assertConfigEquals(newConfig, result);
}
private void setMagnificationActivated(int displayId, int configMode) {
@@ -383,7 +430,7 @@ public class MagnificationProcessorTest {
MAGNIFICATION_MODE_WINDOW)).thenReturn(false);
mFullScreenMagnificationControllerStub.resetAndStubMethods();
mMockFullScreenMagnificationController.setScaleAndCenter(displayId, config.getScale(),
config.getCenterX(), config.getCenterY(), true, SERVICE_ID);
config.getCenterX(), config.getCenterY(), false, SERVICE_ID);
} else if (config.getMode() == MAGNIFICATION_MODE_WINDOW) {
when(mMockMagnificationController.isActivated(displayId,
MAGNIFICATION_MODE_FULLSCREEN)).thenReturn(false);
@@ -429,7 +476,7 @@ public class MagnificationProcessorTest {
};
doAnswer(enableMagnificationStubAnswer).when(
mScreenMagnificationController).setScaleAndCenter(eq(TEST_DISPLAY), anyFloat(),
anyFloat(), anyFloat(), eq(true), eq(SERVICE_ID));
anyFloat(), anyFloat(), anyBoolean(), eq(SERVICE_ID));
Answer registerStubAnswer = invocation -> {
mIsRegistered = true;
@@ -444,6 +491,8 @@ public class MagnificationProcessorTest {
};
doAnswer(unregisterStubAnswer).when(
mScreenMagnificationController).unregister(eq(TEST_DISPLAY));
doAnswer(unregisterStubAnswer).when(
mScreenMagnificationController).reset(eq(TEST_DISPLAY), anyBoolean());
}
public void resetAndStubMethods() {

View File

@@ -20,6 +20,7 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static com.android.server.accessibility.AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID;
import static com.android.server.wm.WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -32,9 +33,9 @@ import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -80,7 +81,6 @@ 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 Rect TEST_RECT = new Rect(0, 50, 100, 51);
private static final float MAGNIFIED_CENTER_X = 100;
private static final float MAGNIFIED_CENTER_Y = 200;
@@ -109,7 +109,8 @@ public class MagnificationControllerTest {
private WindowMagnificationManager mWindowMagnificationManager;
private MockContentResolver mMockResolver;
private MagnificationController mMagnificationController;
private FullScreenMagnificationControllerStubber mScreenMagnificationControllerStubber;
private final WindowMagnificationMgrCallbackDelegate mCallbackDelegate =
new WindowMagnificationMgrCallbackDelegate();
@Mock
private WindowManagerInternal mMockWindowManagerInternal;
@@ -141,17 +142,16 @@ public class MagnificationControllerTest {
mScaleProvider = spy(new MagnificationScaleProvider(mContext));
mWindowMagnificationManager = Mockito.spy(
new WindowMagnificationManager(mContext, globalLock,
mock(WindowMagnificationManager.Callback.class), mTraceManager,
mScaleProvider));
mCallbackDelegate, mTraceManager, mScaleProvider));
mMockConnection = new MockWindowMagnificationConnection(true);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mScreenMagnificationControllerStubber = new FullScreenMagnificationControllerStubber(
mScreenMagnificationController);
new FullScreenMagnificationControllerStubber(mScreenMagnificationController);
mMagnificationController = new MagnificationController(mService, globalLock, mContext,
mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider);
mMagnificationController.setMagnificationCapabilities(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
mCallbackDelegate.setDelegate(mMagnificationController);
}
@After
@@ -222,8 +222,10 @@ public class MagnificationControllerTest {
MODE_WINDOW,
mTransitionCallBack);
mMockConnection.invokeCallbacks();
verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
// The first time is triggered when window mode is activated, the second time is triggered
// when activating the window mode again. The third time is triggered when the transition is
// completed.
verify(mWindowMagnificationManager, times(3)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -247,7 +249,8 @@ public class MagnificationControllerTest {
@Test
public void transitionToFullScreen_centerNotInTheBounds_magnifyBoundsCenter()
throws RemoteException {
final Rect magnificationBounds = MAGNIFICATION_REGION.getBounds();
final Rect magnificationBounds =
FullScreenMagnificationControllerStubber.MAGNIFICATION_REGION.getBounds();
final PointF magnifiedCenter = new PointF(magnificationBounds.right + 100,
magnificationBounds.bottom + 100);
setMagnificationEnabled(MODE_WINDOW, magnifiedCenter.x, magnifiedCenter.y);
@@ -430,18 +433,21 @@ public class MagnificationControllerTest {
}
@Test
public void onSourceBoundsChanged_notifyMagnificationChanged() {
Rect rect = new Rect(0, 0, 100, 120);
Region region = new Region(rect);
mMagnificationController.onSourceBoundsChanged(TEST_DISPLAY, rect);
public void enableWindowMode_notifyMagnificationChanged() throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
verify(mService).notifyMagnificationChanged(eq(TEST_DISPLAY), eq(region),
final ArgumentCaptor<Region> regionCaptor = ArgumentCaptor.forClass(
Region.class);
verify(mService).notifyMagnificationChanged(eq(TEST_DISPLAY), regionCaptor.capture(),
configCaptor.capture());
assertEquals(rect.exactCenterX(), configCaptor.getValue().getCenterX(), 0);
assertEquals(rect.exactCenterY(), configCaptor.getValue().getCenterY(), 0);
final Rect actualRect = regionCaptor.getValue().getBounds();
final MagnificationConfig actualConfig = configCaptor.getValue();
assertEquals(actualRect.exactCenterX(), actualConfig.getCenterX(), 0);
assertEquals(actualRect.exactCenterY(), actualConfig.getCenterY(), 0);
assertEquals(DEFAULT_SCALE, actualConfig.getScale(), 0);
}
@Test
@@ -451,7 +457,8 @@ public class MagnificationControllerTest {
mMagnificationController.onAccessibilityActionPerformed(TEST_DISPLAY);
verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
// The first time is triggered when window mode is activated.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -464,7 +471,8 @@ public class MagnificationControllerTest {
mMagnificationController.onAccessibilityActionPerformed(TEST_DISPLAY);
verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
// The first time is triggered when window mode is activated.
verify(mWindowMagnificationManager, times(2)).removeMagnificationButton(eq(TEST_DISPLAY));
}
@Test
@@ -490,8 +498,7 @@ public class MagnificationControllerTest {
public void onRectangleOnScreenRequested_fullScreenIsActivated_fullScreenDispatchEvent() {
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY,
true);
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
callbacks = getUiChangesForAccessibilityCallbacks();
UiChangesForAccessibilityCallbacks callbacks = getUiChangesForAccessibilityCallbacks();
callbacks.onRectangleOnScreenRequested(TEST_DISPLAY,
TEST_RECT.left, TEST_RECT.top, TEST_RECT.right, TEST_RECT.bottom);
@@ -508,8 +515,7 @@ public class MagnificationControllerTest {
true);
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY,
false);
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
callbacks = getUiChangesForAccessibilityCallbacks();
UiChangesForAccessibilityCallbacks callbacks = getUiChangesForAccessibilityCallbacks();
callbacks.onRectangleOnScreenRequested(TEST_DISPLAY,
TEST_RECT.left, TEST_RECT.top, TEST_RECT.right, TEST_RECT.bottom);
@@ -522,8 +528,7 @@ public class MagnificationControllerTest {
@Test
public void onRectangleOnScreenRequested_NoneIsActivated_noneDispatchEvent() {
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
callbacks = getUiChangesForAccessibilityCallbacks();
UiChangesForAccessibilityCallbacks callbacks = getUiChangesForAccessibilityCallbacks();
callbacks.onRectangleOnScreenRequested(TEST_DISPLAY,
TEST_RECT.left, TEST_RECT.top, TEST_RECT.right, TEST_RECT.bottom);
@@ -546,8 +551,7 @@ public class MagnificationControllerTest {
}
@Test
public void
onFullScreenMagnificationActivationState_fullScreenActivated_logFullScreenDuration() {
public void onFullScreenMagnificationActivationState_fullScreenEnabled_logFullScreenDuration() {
MagnificationController spyController = spy(mMagnificationController);
spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
@@ -596,7 +600,8 @@ public class MagnificationControllerTest {
mMagnificationController.onTouchInteractionStart(TEST_DISPLAY, MODE_WINDOW);
verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
// The first time is triggered when the window mode is activated.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -607,7 +612,8 @@ public class MagnificationControllerTest {
mMagnificationController.onTouchInteractionEnd(TEST_DISPLAY, MODE_WINDOW);
verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
// The first time is triggered when the window mode is activated.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -639,12 +645,10 @@ public class MagnificationControllerTest {
}
@Test
public void onWindowActivated_windowModeEnabledAndCapabilitiesAll_showMagnificationButton()
public void enableWindowMode_showMagnificationButton()
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -661,18 +665,17 @@ public class MagnificationControllerTest {
}
@Test
public void onWindowDeactivated_windowModeInactive_removeMagnificationButton()
public void disableWindowMode_windowModeInActive_removeMagnificationButton()
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, false);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
}
@Test
public void onFullScreenDeactivated_fullscreenModeInactive_removeMagnificationButton()
public void onFullScreenDeactivated_fullscreenModeInActive_removeMagnificationButton()
throws RemoteException {
setMagnificationEnabled(MODE_FULLSCREEN);
mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY,
@@ -685,7 +688,7 @@ public class MagnificationControllerTest {
}
@Test
public void transitionToFullScreenMode_fullscreenModeActivated_showMagnificationButton()
public void transitionToFullScreenMode_fullscreenModeInActive_showMagnificationButton()
throws RemoteException {
setMagnificationEnabled(MODE_WINDOW);
@@ -698,7 +701,7 @@ public class MagnificationControllerTest {
}
@Test
public void transitionToWindow_windowModeActivated_showMagnificationButton()
public void transitionToWindow_fullscreenModeInActive_showMagnificationButton()
throws RemoteException {
setMagnificationEnabled(MODE_FULLSCREEN);
@@ -709,7 +712,10 @@ public class MagnificationControllerTest {
mCallbackArgumentCaptor.capture());
mCallbackArgumentCaptor.getValue().onResult(true);
mMockConnection.invokeCallbacks();
verify(mWindowMagnificationManager).showMagnificationButton(eq(TEST_DISPLAY),
// The first time is triggered when window mode is activated, the second time is triggered
// when the disable-magnification callback is triggered.
verify(mWindowMagnificationManager, times(2)).showMagnificationButton(eq(TEST_DISPLAY),
eq(MODE_WINDOW));
}
@@ -784,7 +790,6 @@ public class MagnificationControllerTest {
}
private void activateMagnifier(int mode, float centerX, float centerY) throws RemoteException {
mScreenMagnificationControllerStubber.resetAndStubMethods();
final boolean windowMagnifying = mWindowMagnificationManager.isWindowMagnifierEnabled(
TEST_DISPLAY);
if (windowMagnifying) {
@@ -806,13 +811,20 @@ public class MagnificationControllerTest {
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, mode, CURRENT_USER_ID);
}
private MagnificationConfig obtainMagnificationConfig(int mode) {
return new MagnificationConfig.Builder().setMode(mode).setScale(DEFAULT_SCALE).setCenterX(
MAGNIFIED_CENTER_X).setCenterY(MAGNIFIED_CENTER_Y).build();
private static MagnificationConfig obtainMagnificationConfig(int mode) {
return obtainMagnificationConfig(mode, true);
}
private WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
getUiChangesForAccessibilityCallbacks() {
private static MagnificationConfig obtainMagnificationConfig(int mode, boolean defaultScale) {
MagnificationConfig.Builder builder = new MagnificationConfig.Builder();
if (defaultScale) {
builder = builder.setScale(DEFAULT_SCALE);
}
return builder.setMode(mode).setCenterX(MAGNIFIED_CENTER_X)
.setCenterY(MAGNIFIED_CENTER_Y).build();
}
private UiChangesForAccessibilityCallbacks getUiChangesForAccessibilityCallbacks() {
ArgumentCaptor<WindowManagerInternal.AccessibilityControllerInternal
.UiChangesForAccessibilityCallbacks> captor = ArgumentCaptor.forClass(
WindowManagerInternal.AccessibilityControllerInternal
@@ -822,21 +834,65 @@ public class MagnificationControllerTest {
return captor.getValue();
}
private static class WindowMagnificationMgrCallbackDelegate implements
WindowMagnificationManager.Callback {
private WindowMagnificationManager.Callback mCallback;
public void setDelegate(WindowMagnificationManager.Callback callback) {
mCallback = callback;
}
@Override
public void onPerformScaleAction(int displayId, float scale) {
if (mCallback != null) {
mCallback.onPerformScaleAction(displayId, scale);
}
}
@Override
public void onAccessibilityActionPerformed(int displayId) {
if (mCallback != null) {
mCallback.onAccessibilityActionPerformed(displayId);
}
}
@Override
public void onWindowMagnificationActivationState(int displayId, boolean activated) {
if (mCallback != null) {
mCallback.onWindowMagnificationActivationState(displayId, activated);
}
}
@Override
public void onSourceBoundsChanged(int displayId, Rect bounds) {
if (mCallback != null) {
mCallback.onSourceBoundsChanged(displayId, bounds);
}
}
@Override
public void onChangeMagnificationMode(int displayId, int magnificationMode) {
if (mCallback != null) {
mCallback.onChangeMagnificationMode(displayId, magnificationMode);
}
}
}
/**
* Stubs public methods to simulate the real beahviours.
* Stubs public methods to simulate the real behaviours.
*/
private static class FullScreenMagnificationControllerStubber {
private static final Region MAGNIFICATION_REGION = new Region(0, 0, 500, 600);
private final FullScreenMagnificationController mScreenMagnificationController;
private boolean mIsMagnifying = false;
private float mScale = 1.0f;
private float mCenterX = 0;
private float mCenterY = 0;
private float mCenterX = MAGNIFICATION_REGION.getBounds().exactCenterX();
private float mCenterY = MAGNIFICATION_REGION.getBounds().exactCenterY();
private int mServiceId = -1;
FullScreenMagnificationControllerStubber(
FullScreenMagnificationController screenMagnificationController) {
mScreenMagnificationController = screenMagnificationController;
resetCenter();
stubMethods();
}
@@ -872,8 +928,7 @@ public class MagnificationControllerTest {
mCenterY = invocation.getArgument(3);
mServiceId = invocation.getArgument(5);
} else {
mServiceId = -1;
resetCenter();
reset();
}
return true;
};
@@ -886,26 +941,21 @@ public class MagnificationControllerTest {
anyFloat(), anyFloat(), anyFloat(), anyBoolean(), anyInt());
Answer resetStubAnswer = invocation -> {
mScale = 1.0f;
mIsMagnifying = false;
mServiceId = -1;
resetCenter();
reset();
return true;
};
doAnswer(resetStubAnswer).when(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
any());
any(MagnificationAnimationCallback.class));
doAnswer(resetStubAnswer).when(mScreenMagnificationController).reset(eq(TEST_DISPLAY),
anyBoolean());
}
private void resetCenter() {
private void reset() {
mScale = 1.0f;
mIsMagnifying = false;
mServiceId = -1;
mCenterX = MAGNIFICATION_REGION.getBounds().exactCenterX();
mCenterY = MAGNIFICATION_REGION.getBounds().exactCenterY();
}
public void resetAndStubMethods() {
Mockito.reset(mScreenMagnificationController);
stubMethods();
}
}
}

View File

@@ -62,6 +62,7 @@ import com.android.server.statusbar.StatusBarManagerInternal;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
@@ -633,9 +634,15 @@ public class WindowMagnificationManagerTest {
public void onWindowMagnificationActivationState_magnifierDisabled_notifyDeactivatedState() {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, NaN, NaN);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, true);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
verify(mMockCallback).onWindowMagnificationActivationState(TEST_DISPLAY, false);
Mockito.reset(mMockCallback);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
verify(mMockCallback, never()).onWindowMagnificationActivationState(eq(TEST_DISPLAY),
anyBoolean());
}
private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {