Resets the window magnifier after the a11y service is unbinded

After the service connection is ubineded or the binder died,
a11y framework should reset all the magnifiers that had been
controlled by the service connection.
Now the framework should also support reseting the
window magnfiers that had been controlled by the service.

Bug: 203532041
Test: atest AccessibilityMagnificationTest,
  atest AccessibilityServiceConnectionTest,
  atest MagnificationProcessorTest,
  atest MagnificationControllerTest,
  atest WindowMagnificationManagerTest,
Change-Id: I605a2cb17e3fb6677b9da0715ca7d7a84af70295
This commit is contained in:
mincheli
2021-12-08 21:22:42 +08:00
committed by Minche Li
parent 4c9a0a0dca
commit 58ec92d10b
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);