Merge "Resets the window magnifier after the a11y service is unbinded"

This commit is contained in:
Minche Li
2021-12-29 00:06:33 +00:00
committed by Android (Google) Code Review
10 changed files with 205 additions and 77 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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);
}
/**

View File

@@ -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.
* <p>
* This class requires to hold the lock when controlling the magnifier.
* </p>
*/
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();
}
}

View File

@@ -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());
}
}

View File

@@ -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() {

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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);