Support individual magnification mode for each display
Currently we only have a globale magnification mode which
is stored in settings. It ends up the mode is shared between
multi-displays. To provide better experience, we store the mode
for each none-default display until the device reboot,
and the default mode is full-screen.
Test: atest com.android.server.accessibility
atest com.android.systemui.accessibility
Bug: 194667380
Change-Id: I099e1ee945938aac07cc079f68bccbc745d40b08
This commit is contained in:
@@ -28,7 +28,6 @@ import android.graphics.Insets;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.MathUtils;
|
||||
import android.view.Gravity;
|
||||
@@ -75,6 +74,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
|
||||
private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
|
||||
private int mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
|
||||
private final LayoutParams mParams;
|
||||
private final SwitchListener mSwitchListener;
|
||||
@VisibleForTesting
|
||||
final Rect mDraggableWindowBounds = new Rect();
|
||||
private boolean mIsVisible = false;
|
||||
@@ -82,17 +82,29 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
|
||||
private boolean mSingleTapDetected = false;
|
||||
private boolean mToLeftScreenEdge = false;
|
||||
|
||||
MagnificationModeSwitch(@UiContext Context context) {
|
||||
this(context, createView(context), new SfVsyncFrameCallbackProvider());
|
||||
public interface SwitchListener {
|
||||
/**
|
||||
* Called when the switch is clicked to change the magnification mode.
|
||||
* @param displayId the display id of the display to which the view's window has been
|
||||
* attached
|
||||
* @param magnificationMode the magnification mode
|
||||
*/
|
||||
void onSwitch(int displayId, int magnificationMode);
|
||||
}
|
||||
|
||||
MagnificationModeSwitch(@UiContext Context context,
|
||||
SwitchListener switchListener) {
|
||||
this(context, createView(context), new SfVsyncFrameCallbackProvider(), switchListener);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
MagnificationModeSwitch(Context context, @NonNull ImageView imageView,
|
||||
SfVsyncFrameCallbackProvider sfVsyncFrameProvider) {
|
||||
SfVsyncFrameCallbackProvider sfVsyncFrameProvider, SwitchListener switchListener) {
|
||||
mContext = context;
|
||||
mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
|
||||
mWindowManager = mContext.getSystemService(WindowManager.class);
|
||||
mSfVsyncFrameProvider = sfVsyncFrameProvider;
|
||||
mSwitchListener = switchListener;
|
||||
mParams = createLayoutParams(context);
|
||||
mImageView = imageView;
|
||||
mImageView.setOnTouchListener(this::onTouch);
|
||||
@@ -364,11 +376,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL
|
||||
mMagnificationMode ^ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
|
||||
mMagnificationMode = newMode;
|
||||
mImageView.setImageResource(getIconResId(newMode));
|
||||
Settings.Secure.putIntForUser(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
|
||||
newMode,
|
||||
UserHandle.USER_CURRENT);
|
||||
mSwitchListener.onSwitch(mContext.getDisplayId(), newMode);
|
||||
}
|
||||
|
||||
private void handleSingleTap() {
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.systemui.accessibility;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
|
||||
|
||||
import static com.android.systemui.accessibility.MagnificationModeSwitch.SwitchListener;
|
||||
|
||||
import android.annotation.MainThread;
|
||||
import android.content.Context;
|
||||
import android.hardware.display.DisplayManager;
|
||||
@@ -27,21 +29,24 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
|
||||
/**
|
||||
* A class to control {@link MagnificationModeSwitch}. It should show the button UI with following
|
||||
* A class to control {@link MagnificationModeSwitch}. It shows the button UI with following
|
||||
* conditions:
|
||||
* <ol>
|
||||
* <li> Both full-screen and window magnification mode are capable.</li>
|
||||
* <li> The magnification scale is changed by a user.</li>
|
||||
* <ol>
|
||||
* The switch action will be handled by {@link #mSwitchListenerDelegate} which informs the system
|
||||
* server about the changed mode.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class ModeSwitchesController {
|
||||
public class ModeSwitchesController implements SwitchListener {
|
||||
|
||||
private final DisplayIdIndexSupplier<MagnificationModeSwitch> mSwitchSupplier;
|
||||
private SwitchListener mSwitchListenerDelegate;
|
||||
|
||||
public ModeSwitchesController(Context context) {
|
||||
mSwitchSupplier = new SwitchSupplier(context,
|
||||
context.getSystemService(DisplayManager.class));
|
||||
context.getSystemService(DisplayManager.class), this::onSwitch);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -50,8 +55,8 @@ public class ModeSwitchesController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a button that a user can click the button to switch magnification mode. And the
|
||||
* button would be dismissed automatically after the button is displayed for a period of time.
|
||||
* Shows a button that a user can click to switch magnification mode. And the button
|
||||
* would be dismissed automatically after the button is displayed for a period of time.
|
||||
*
|
||||
* @param displayId The logical display id
|
||||
* @param mode The magnification mode
|
||||
@@ -93,24 +98,41 @@ public class ModeSwitchesController {
|
||||
switchController -> switchController.onConfigurationChanged(configDiff));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwitch(int displayId, int magnificationMode) {
|
||||
if (mSwitchListenerDelegate != null) {
|
||||
mSwitchListenerDelegate.onSwitch(displayId, magnificationMode);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSwitchListenerDelegate(SwitchListener switchListenerDelegate) {
|
||||
mSwitchListenerDelegate = switchListenerDelegate;
|
||||
}
|
||||
|
||||
private static class SwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
|
||||
|
||||
private final Context mContext;
|
||||
private final SwitchListener mSwitchListener;
|
||||
|
||||
/**
|
||||
* Supplies the switch for the given display.
|
||||
*
|
||||
* @param context Context
|
||||
* @param displayManager DisplayManager
|
||||
* @param switchListener The callback that will run when the switch is clicked
|
||||
*/
|
||||
SwitchSupplier(Context context, DisplayManager displayManager) {
|
||||
SwitchSupplier(Context context, DisplayManager displayManager,
|
||||
SwitchListener switchListener) {
|
||||
super(displayManager);
|
||||
mContext = context;
|
||||
mSwitchListener = switchListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MagnificationModeSwitch createInstance(Display display) {
|
||||
final Context uiContext = mContext.createWindowContext(display,
|
||||
TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, /* options */ null);
|
||||
return new MagnificationModeSwitch(uiContext);
|
||||
return new MagnificationModeSwitch(uiContext, mSwitchListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,12 +243,15 @@ public class WindowMagnification extends SystemUI implements WindowMagnifierCall
|
||||
mWindowMagnificationConnectionImpl = new WindowMagnificationConnectionImpl(this,
|
||||
mHandler, mModeSwitchesController);
|
||||
}
|
||||
mModeSwitchesController.setSwitchListenerDelegate(
|
||||
mWindowMagnificationConnectionImpl::onChangeMagnificationMode);
|
||||
mAccessibilityManager.setWindowMagnificationConnection(
|
||||
mWindowMagnificationConnectionImpl);
|
||||
}
|
||||
|
||||
private void clearWindowMagnificationConnection() {
|
||||
mAccessibilityManager.setWindowMagnificationConnection(null);
|
||||
mModeSwitchesController.setSwitchListenerDelegate(null);
|
||||
//TODO: destroy controllers.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,4 +130,14 @@ class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.S
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onChangeMagnificationMode(int displayId, int mode) {
|
||||
if (mConnectionCallback != null) {
|
||||
try {
|
||||
mConnectionCallback.onChangeMagnificationMode(displayId, mode);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to inform changing magnification mode", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,10 +55,9 @@ import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.Choreographer;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -101,6 +100,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
@Mock
|
||||
private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
|
||||
private SwitchListenerStub mSwitchListener;
|
||||
private TestableWindowManager mWindowManager;
|
||||
private ViewPropertyAnimator mViewPropertyAnimator;
|
||||
private MagnificationModeSwitch mMagnificationModeSwitch;
|
||||
@@ -112,6 +112,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final WindowManager wm = mContext.getSystemService(WindowManager.class);
|
||||
mSwitchListener = new SwitchListenerStub();
|
||||
mWindowManager = spy(new TestableWindowManager(wm));
|
||||
mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
|
||||
mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager);
|
||||
@@ -130,7 +131,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
}).when(mSfVsyncFrameProvider).postFrameCallback(
|
||||
any(Choreographer.FrameCallback.class));
|
||||
mMagnificationModeSwitch = new MagnificationModeSwitch(mContext, mSpyImageView,
|
||||
mSfVsyncFrameProvider);
|
||||
mSfVsyncFrameProvider, mSwitchListener);
|
||||
assertNotNull(mTouchListener);
|
||||
}
|
||||
|
||||
@@ -326,8 +327,6 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
public void performDragging_showMagnificationButton_updateViewLayout() {
|
||||
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
|
||||
resetAndStubMockImageViewAndAnimator();
|
||||
final int previousMode = Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0, UserHandle.USER_CURRENT);
|
||||
|
||||
// Perform dragging
|
||||
final int offset = ViewConfiguration.get(mContext).getScaledTouchSlop() + 10;
|
||||
@@ -345,7 +344,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
|
||||
downTime, downTime, ACTION_UP, 100 + offset, 100));
|
||||
|
||||
assertModeUnchanged(previousMode);
|
||||
assertModeUnchanged();
|
||||
assertShowFadingAnimation(FADE_OUT_ALPHA);
|
||||
}
|
||||
|
||||
@@ -353,8 +352,6 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
public void performSingleTapActionCanceled_showButtonAnimation() {
|
||||
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
|
||||
resetAndStubMockImageViewAndAnimator();
|
||||
final int previousMode = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0);
|
||||
|
||||
final long downTime = SystemClock.uptimeMillis();
|
||||
mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
|
||||
@@ -363,7 +360,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
|
||||
downTime, downTime, ACTION_CANCEL, 100, 100));
|
||||
|
||||
assertModeUnchanged(previousMode);
|
||||
assertModeUnchanged();
|
||||
assertShowFadingAnimation(FADE_OUT_ALPHA);
|
||||
}
|
||||
|
||||
@@ -371,8 +368,6 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
public void performDraggingActionCanceled_showButtonAnimation() {
|
||||
mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
|
||||
resetAndStubMockImageViewAndAnimator();
|
||||
final int previousMode = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0);
|
||||
|
||||
// Perform dragging
|
||||
final long downTime = SystemClock.uptimeMillis();
|
||||
@@ -385,7 +380,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
mTouchListener.onTouch(mSpyImageView, obtainMotionEvent(
|
||||
downTime, downTime, ACTION_CANCEL, 100 + offset, 100));
|
||||
|
||||
assertModeUnchanged(previousMode);
|
||||
assertModeUnchanged();
|
||||
assertShowFadingAnimation(FADE_OUT_ALPHA);
|
||||
}
|
||||
|
||||
@@ -529,10 +524,9 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
assertEquals(expectedY, mWindowManager.getLayoutParamsFromAttachedView().y);
|
||||
}
|
||||
|
||||
private void assertModeUnchanged(int expectedMode) {
|
||||
final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0);
|
||||
assertEquals(expectedMode, actualMode);
|
||||
private void assertModeUnchanged() {
|
||||
assertEquals(SwitchListenerStub.MODE_INVALID,
|
||||
mSwitchListener.getChangedMode(mContext.getDisplayId()));
|
||||
}
|
||||
|
||||
private void assertShowFadingAnimation(float alpha) {
|
||||
@@ -594,9 +588,8 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
verify(mSpyImageView).setImageResource(
|
||||
getIconResId(expectedMode));
|
||||
verify(mWindowManager).removeView(mSpyImageView);
|
||||
final int actualMode = Settings.Secure.getIntForUser(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0, UserHandle.USER_CURRENT);
|
||||
assertEquals(expectedMode, actualMode);
|
||||
final int changedMode = mSwitchListener.getChangedMode(mContext.getDisplayId());
|
||||
assertEquals(expectedMode, changedMode);
|
||||
}
|
||||
|
||||
private MotionEvent obtainMotionEvent(long downTime, long eventTime, int action, float x,
|
||||
@@ -621,4 +614,20 @@ public class MagnificationModeSwitchTest extends SysuiTestCase {
|
||||
assertEquals(expectedX, layoutParams.x);
|
||||
assertEquals(expectedY, layoutParams.y);
|
||||
}
|
||||
|
||||
private static class SwitchListenerStub implements MagnificationModeSwitch.SwitchListener {
|
||||
|
||||
private static final int MODE_INVALID = -1;
|
||||
|
||||
private final SparseIntArray mModes = new SparseIntArray();
|
||||
|
||||
@Override
|
||||
public void onSwitch(int displayId, int magnificationMode) {
|
||||
mModes.put(displayId, magnificationMode);
|
||||
}
|
||||
|
||||
int getChangedMode(int displayId) {
|
||||
return mModes.get(displayId, MODE_INVALID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,27 +22,32 @@ import android.content.pm.ActivityInfo;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.provider.Settings;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.Display;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
/** Tests the ModeSwitchesController. */
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
public class ModeSwitchesControllerTest extends SysuiTestCase {
|
||||
|
||||
private FakeSwitchSupplier mSupplier;
|
||||
@Mock
|
||||
private MagnificationModeSwitch mModeSwitch;
|
||||
private ModeSwitchesController mModeSwitchesController;
|
||||
@Mock
|
||||
private MagnificationModeSwitch.SwitchListener mListener;
|
||||
|
||||
|
||||
@Before
|
||||
@@ -50,6 +55,13 @@ public class ModeSwitchesControllerTest extends SysuiTestCase {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mSupplier = new FakeSwitchSupplier(mContext.getSystemService(DisplayManager.class));
|
||||
mModeSwitchesController = new ModeSwitchesController(mSupplier);
|
||||
mModeSwitchesController.setSwitchListenerDelegate(mListener);
|
||||
mModeSwitch = Mockito.spy(new MagnificationModeSwitch(mContext, mModeSwitchesController));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mModeSwitchesController.removeButton(Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -79,6 +91,18 @@ public class ModeSwitchesControllerTest extends SysuiTestCase {
|
||||
verify(mModeSwitch).onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOnSwitchClick_showWindowModeButton_invokeListener() {
|
||||
mModeSwitchesController.showButton(Display.DEFAULT_DISPLAY,
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
|
||||
mModeSwitch.onSingleTap();
|
||||
|
||||
verify(mListener).onSwitch(mContext.getDisplayId(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
|
||||
}
|
||||
|
||||
private class FakeSwitchSupplier extends DisplayIdIndexSupplier<MagnificationModeSwitch> {
|
||||
|
||||
FakeSwitchSupplier(DisplayManager displayManager) {
|
||||
|
||||
@@ -22,6 +22,8 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_M
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.notNull;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -99,17 +101,19 @@ public class WindowMagnificationTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWindowMagnificationConnection_setWindowMagnificationConnection() {
|
||||
public void requestWindowMagnificationConnection_setConnectionAndListener() {
|
||||
mCommandQueue.requestWindowMagnificationConnection(true);
|
||||
waitForIdleSync();
|
||||
|
||||
verify(mAccessibilityManager).setWindowMagnificationConnection(any(
|
||||
IWindowMagnificationConnection.class));
|
||||
verify(mModeSwitchesController).setSwitchListenerDelegate(notNull());
|
||||
|
||||
mCommandQueue.requestWindowMagnificationConnection(false);
|
||||
waitForIdleSync();
|
||||
|
||||
verify(mAccessibilityManager).setWindowMagnificationConnection(null);
|
||||
verify(mAccessibilityManager).setWindowMagnificationConnection(isNull());
|
||||
verify(mModeSwitchesController).setSwitchListenerDelegate(isNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -272,6 +272,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
return getUserStateLocked(mCurrentUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the magnification mode on the given display.
|
||||
*
|
||||
* @param displayId the logical display
|
||||
* @param magnificationMode the target magnification mode
|
||||
*/
|
||||
public void changeMagnificationMode(int displayId, int magnificationMode) {
|
||||
synchronized (mLock) {
|
||||
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||
persistMagnificationModeSettingsLocked(magnificationMode);
|
||||
} else {
|
||||
final AccessibilityUserState userState = getCurrentUserStateLocked();
|
||||
final int currentMode = userState.getMagnificationModeLocked(displayId);
|
||||
if (magnificationMode != currentMode) {
|
||||
userState.setMagnificationModeLocked(displayId, magnificationMode);
|
||||
updateMagnificationModeChangeSettingsLocked(userState, displayId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Lifecycle extends SystemService {
|
||||
private final AccessibilityManagerService mService;
|
||||
|
||||
@@ -299,7 +320,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
SystemActionPerformer systemActionPerformer,
|
||||
AccessibilityWindowManager a11yWindowManager,
|
||||
AccessibilityDisplayListener a11yDisplayListener,
|
||||
MagnificationController magnificationController) {
|
||||
MagnificationController magnificationController,
|
||||
@Nullable AccessibilityInputFilter inputFilter) {
|
||||
mContext = context;
|
||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
mWindowManagerService = LocalServices.getService(WindowManagerInternal.class);
|
||||
@@ -314,6 +336,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
mA11yDisplayListener = a11yDisplayListener;
|
||||
mMagnificationController = magnificationController;
|
||||
mMagnificationProcessor = new MagnificationProcessor(mMagnificationController);
|
||||
if (inputFilter != null) {
|
||||
mInputFilter = inputFilter;
|
||||
mHasInputFilter = true;
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -1794,47 +1820,51 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
return relevantEventTypes;
|
||||
}
|
||||
|
||||
private void updateMagnificationModeChangeSettingsLocked(AccessibilityUserState userState) {
|
||||
private void updateMagnificationModeChangeSettingsLocked(AccessibilityUserState userState,
|
||||
int displayId) {
|
||||
if (userState.mUserId != mCurrentUserId) {
|
||||
return;
|
||||
}
|
||||
// New mode is invalid, so ignore and restore it.
|
||||
if (fallBackMagnificationModeSettingsLocked(userState)) {
|
||||
if (fallBackMagnificationModeSettingsLocked(userState, displayId)) {
|
||||
return;
|
||||
}
|
||||
mMagnificationController.transitionMagnificationModeLocked(
|
||||
Display.DEFAULT_DISPLAY, userState.getMagnificationModeLocked(),
|
||||
displayId, userState.getMagnificationModeLocked(displayId),
|
||||
this::onMagnificationTransitionEndedLocked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the magnification mode transition is completed.
|
||||
* Called when the magnification mode transition is completed. If the given display is default
|
||||
* display, we also need to fall back the mode in user settings.
|
||||
*/
|
||||
void onMagnificationTransitionEndedLocked(boolean success) {
|
||||
void onMagnificationTransitionEndedLocked(int displayId, boolean success) {
|
||||
final AccessibilityUserState userState = getCurrentUserStateLocked();
|
||||
final int previousMode = userState.getMagnificationModeLocked()
|
||||
final int previousMode = userState.getMagnificationModeLocked(displayId)
|
||||
^ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
|
||||
if (!success && previousMode != 0) {
|
||||
userState.setMagnificationModeLocked(previousMode);
|
||||
persistMagnificationModeSettingLocked(previousMode);
|
||||
userState.setMagnificationModeLocked(displayId, previousMode);
|
||||
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||
persistMagnificationModeSettingsLocked(previousMode);
|
||||
}
|
||||
} else {
|
||||
mMainHandler.sendMessage(obtainMessage(
|
||||
AccessibilityManagerService::notifyRefreshMagnificationModeToInputFilter,
|
||||
this));
|
||||
this, displayId));
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyRefreshMagnificationModeToInputFilter() {
|
||||
private void notifyRefreshMagnificationModeToInputFilter(int displayId) {
|
||||
synchronized (mLock) {
|
||||
if (!mHasInputFilter) {
|
||||
return;
|
||||
}
|
||||
// TODO: notify the mode change on specified display.
|
||||
final ArrayList<Display> displays = getValidDisplayList();
|
||||
for (int i = 0; i < displays.size(); i++) {
|
||||
final Display display = displays.get(i);
|
||||
if (display != null) {
|
||||
if (display != null && display.getDisplayId() == displayId) {
|
||||
mInputFilter.refreshMagnificationMode(display);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2245,12 +2275,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
scheduleUpdateClientsIfNeededLocked(userState);
|
||||
updateAccessibilityShortcutKeyTargetsLocked(userState);
|
||||
updateAccessibilityButtonTargetsLocked(userState);
|
||||
// Update the capabilities before the mode.
|
||||
// Update the capabilities before the mode because we will check the current mode is
|
||||
// invalid or not..
|
||||
updateMagnificationCapabilitiesSettingsChangeLocked(userState);
|
||||
updateMagnificationModeChangeSettingsLocked(userState);
|
||||
updateMagnificationModeChangeSettingsForAllDisplaysLocked(userState);
|
||||
updateFocusAppearanceDataLocked(userState);
|
||||
}
|
||||
|
||||
private void updateMagnificationModeChangeSettingsForAllDisplaysLocked(
|
||||
AccessibilityUserState userState) {
|
||||
final ArrayList<Display> displays = getValidDisplayList();
|
||||
for (int i = 0; i < displays.size(); i++) {
|
||||
final int displayId = displays.get(i).getDisplayId();
|
||||
updateMagnificationModeChangeSettingsLocked(userState, displayId);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateWindowsForAccessibilityCallbackLocked(AccessibilityUserState userState) {
|
||||
// We observe windows for accessibility only if there is at least
|
||||
// one bound service that can retrieve window content that specified
|
||||
@@ -2348,7 +2388,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
somethingChanged |= readAccessibilityButtonTargetsLocked(userState);
|
||||
somethingChanged |= readAccessibilityButtonTargetComponentLocked(userState);
|
||||
somethingChanged |= readUserRecommendedUiTimeoutSettingsLocked(userState);
|
||||
somethingChanged |= readMagnificationModeLocked(userState);
|
||||
somethingChanged |= readMagnificationModeForDefaultDisplayLocked(userState);
|
||||
somethingChanged |= readMagnificationCapabilitiesLocked(userState);
|
||||
return somethingChanged;
|
||||
}
|
||||
@@ -3878,8 +3918,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
|| mUserInteractiveUiTimeoutUri.equals(uri)) {
|
||||
readUserRecommendedUiTimeoutSettingsLocked(userState);
|
||||
} else if (mMagnificationModeUri.equals(uri)) {
|
||||
if (readMagnificationModeLocked(userState)) {
|
||||
updateMagnificationModeChangeSettingsLocked(userState);
|
||||
if (readMagnificationModeForDefaultDisplayLocked(userState)) {
|
||||
updateMagnificationModeChangeSettingsLocked(userState,
|
||||
Display.DEFAULT_DISPLAY);
|
||||
}
|
||||
} else if (mMagnificationCapabilityUri.equals(uri)) {
|
||||
if (readMagnificationCapabilitiesLocked(userState)) {
|
||||
@@ -3892,8 +3933,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
|
||||
private void updateMagnificationCapabilitiesSettingsChangeLocked(
|
||||
AccessibilityUserState userState) {
|
||||
if (fallBackMagnificationModeSettingsLocked(userState)) {
|
||||
updateMagnificationModeChangeSettingsLocked(userState);
|
||||
final ArrayList<Display> displays = getValidDisplayList();
|
||||
for (int i = 0; i < displays.size(); i++) {
|
||||
final int displayId = displays.get(i).getDisplayId();
|
||||
if (fallBackMagnificationModeSettingsLocked(userState, displayId)) {
|
||||
updateMagnificationModeChangeSettingsLocked(userState, displayId);
|
||||
}
|
||||
}
|
||||
updateWindowMagnificationConnectionIfNeeded(userState);
|
||||
// Remove magnification button UI when the magnification capability is not all mode or
|
||||
@@ -3902,7 +3947,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
|| userState.isShortcutMagnificationEnabledLocked())
|
||||
|| userState.getMagnificationCapabilitiesLocked()
|
||||
!= Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) {
|
||||
final ArrayList<Display> displays = getValidDisplayList();
|
||||
|
||||
for (int i = 0; i < displays.size(); i++) {
|
||||
final int displayId = displays.get(i).getDisplayId();
|
||||
getWindowMagnificationMgr().removeMagnificationButton(displayId);
|
||||
@@ -3910,18 +3955,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private boolean fallBackMagnificationModeSettingsLocked(AccessibilityUserState userState) {
|
||||
if (userState.isValidMagnificationModeLocked()) {
|
||||
private boolean fallBackMagnificationModeSettingsLocked(AccessibilityUserState userState,
|
||||
int displayId) {
|
||||
if (userState.isValidMagnificationModeLocked(displayId)) {
|
||||
return false;
|
||||
}
|
||||
Slog.w(LOG_TAG, "invalid magnification mode:" + userState.getMagnificationModeLocked());
|
||||
Slog.w(LOG_TAG, "displayId " + displayId + ", invalid magnification mode:"
|
||||
+ userState.getMagnificationModeLocked(displayId));
|
||||
final int capabilities = userState.getMagnificationCapabilitiesLocked();
|
||||
userState.setMagnificationModeLocked(capabilities);
|
||||
persistMagnificationModeSettingLocked(capabilities);
|
||||
userState.setMagnificationModeLocked(displayId, capabilities);
|
||||
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||
persistMagnificationModeSettingsLocked(capabilities);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void persistMagnificationModeSettingLocked(int mode) {
|
||||
private void persistMagnificationModeSettingsLocked(int mode) {
|
||||
BackgroundThread.getHandler().post(() -> {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -3933,7 +3982,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
});
|
||||
}
|
||||
|
||||
//TODO: support multi-display.
|
||||
/**
|
||||
* Gets the magnification mode of the specified display.
|
||||
*
|
||||
@@ -3943,17 +3991,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
*/
|
||||
public int getMagnificationMode(int displayId) {
|
||||
synchronized (mLock) {
|
||||
return getCurrentUserStateLocked().getMagnificationModeLocked();
|
||||
return getCurrentUserStateLocked().getMagnificationModeLocked(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean readMagnificationModeLocked(AccessibilityUserState userState) {
|
||||
// Only the value of the default display is from user settings because not each of displays has
|
||||
// a unique id.
|
||||
private boolean readMagnificationModeForDefaultDisplayLocked(AccessibilityUserState userState) {
|
||||
final int magnificationMode = Settings.Secure.getIntForUser(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN, userState.mUserId);
|
||||
if (magnificationMode != userState.getMagnificationModeLocked()) {
|
||||
userState.setMagnificationModeLocked(magnificationMode);
|
||||
if (magnificationMode != userState.getMagnificationModeLocked(Display.DEFAULT_DISPLAY)) {
|
||||
userState.setMagnificationModeLocked(Display.DEFAULT_DISPLAY, magnificationMode);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN
|
||||
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_IGNORE_HARD_KEYBOARD;
|
||||
import static android.accessibilityservice.AccessibilityService.SHOW_MODE_MASK;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
|
||||
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
|
||||
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
|
||||
import static android.view.accessibility.AccessibilityManager.ShortcutType;
|
||||
@@ -42,6 +43,7 @@ import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.accessibility.IAccessibilityManagerClient;
|
||||
|
||||
@@ -122,8 +124,8 @@ class AccessibilityUserState {
|
||||
|
||||
/** {@code true} if the device config supports magnification area. */
|
||||
private final boolean mSupportMagnificationArea;
|
||||
// The magnification mode of default display.
|
||||
private int mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
|
||||
// The magnification modes on displays.
|
||||
private final SparseIntArray mMagnificationModes = new SparseIntArray();
|
||||
// The magnification capabilities used to know magnification mode could be switched.
|
||||
private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
|
||||
|
||||
@@ -141,12 +143,13 @@ class AccessibilityUserState {
|
||||
@SoftKeyboardShowMode
|
||||
private int mSoftKeyboardShowMode = SHOW_MODE_AUTO;
|
||||
|
||||
boolean isValidMagnificationModeLocked() {
|
||||
boolean isValidMagnificationModeLocked(int displayId) {
|
||||
final int mode = getMagnificationModeLocked(displayId);
|
||||
if (!mSupportMagnificationArea
|
||||
&& mMagnificationMode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
|
||||
&& mode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
|
||||
return false;
|
||||
}
|
||||
return (mMagnificationCapabilities & mMagnificationMode) != 0;
|
||||
return (mMagnificationCapabilities & mode) != 0;
|
||||
}
|
||||
|
||||
interface ServiceInfoChangeListener {
|
||||
@@ -203,7 +206,7 @@ class AccessibilityUserState {
|
||||
mIsAutoclickEnabled = false;
|
||||
mUserNonInteractiveUiTimeout = 0;
|
||||
mUserInteractiveUiTimeout = 0;
|
||||
mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
|
||||
mMagnificationModes.clear();
|
||||
mFocusStrokeWidth = mFocusStrokeWidthDefaultValue;
|
||||
mFocusColor = mFocusColorDefaultValue;
|
||||
}
|
||||
@@ -500,7 +503,7 @@ class AccessibilityUserState {
|
||||
pw.append(", nonInteractiveUiTimeout=").append(String.valueOf(mNonInteractiveUiTimeout));
|
||||
pw.append(", interactiveUiTimeout=").append(String.valueOf(mInteractiveUiTimeout));
|
||||
pw.append(", installedServiceCount=").append(String.valueOf(mInstalledServices.size()));
|
||||
pw.append(", magnificationMode=").append(String.valueOf(mMagnificationMode));
|
||||
pw.append(", magnificationModes=").append(String.valueOf(mMagnificationModes));
|
||||
pw.append(", magnificationCapabilities=")
|
||||
.append(String.valueOf(mMagnificationCapabilities));
|
||||
pw.append("}");
|
||||
@@ -635,14 +638,19 @@ class AccessibilityUserState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the magnification mode of default display.
|
||||
* Gets the magnification mode for the given display.
|
||||
* @return magnification mode
|
||||
*
|
||||
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
|
||||
* @see Settings.Secure#ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
|
||||
*/
|
||||
public int getMagnificationModeLocked() {
|
||||
return mMagnificationMode;
|
||||
public int getMagnificationModeLocked(int displayId) {
|
||||
int mode = mMagnificationModes.get(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_NONE);
|
||||
if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) {
|
||||
mode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
|
||||
setMagnificationModeLocked(displayId, mode);
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -671,11 +679,13 @@ class AccessibilityUserState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the magnification mode of default display.
|
||||
* Sets the magnification mode to the given display.
|
||||
*
|
||||
* @param displayId The display id.
|
||||
* @param mode The magnification mode.
|
||||
*/
|
||||
public void setMagnificationModeLocked(int mode) {
|
||||
mMagnificationMode = mode;
|
||||
public void setMagnificationModeLocked(int displayId, int mode) {
|
||||
mMagnificationModes.put(displayId, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -208,8 +208,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
}
|
||||
mPromptController.onDestroy();
|
||||
// Check if need to reset when MagnificationGestureHandler is the last magnifying service.
|
||||
mFullScreenMagnificationController.resetAllIfNeeded(
|
||||
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
|
||||
mFullScreenMagnificationController.resetIfNeeded(
|
||||
mDisplayId, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
|
||||
clearAndTransitionToStateDetecting();
|
||||
}
|
||||
|
||||
|
||||
@@ -92,14 +92,16 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
private long mFullScreenModeEnabledTime = 0;
|
||||
|
||||
/**
|
||||
* A callback to inform the magnification transition result.
|
||||
* A callback to inform the magnification transition result on the given display.
|
||||
*/
|
||||
public interface TransitionCallBack {
|
||||
/**
|
||||
* Invoked when the transition ends.
|
||||
*
|
||||
* @param displayId The display id.
|
||||
* @param success {@code true} if the transition success.
|
||||
*/
|
||||
void onResult(boolean success);
|
||||
void onResult(int displayId, boolean success);
|
||||
}
|
||||
|
||||
public MagnificationController(AccessibilityManagerService ams, Object lock,
|
||||
@@ -179,7 +181,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
final DisableMagnificationCallback animationCallback =
|
||||
getDisableMagnificationEndRunnableLocked(displayId);
|
||||
if (magnificationCenter == null && animationCallback == null) {
|
||||
transitionCallBack.onResult(true);
|
||||
transitionCallBack.onResult(displayId, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,7 +197,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
|
||||
if (magnificationCenter == null) {
|
||||
Slog.w(TAG, "Invalid center, ignore it");
|
||||
transitionCallBack.onResult(true);
|
||||
transitionCallBack.onResult(displayId, true);
|
||||
return;
|
||||
}
|
||||
final FullScreenMagnificationController screenMagnificationController =
|
||||
@@ -251,6 +253,11 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeMagnificationMode(int displayId, int magnificationMode) {
|
||||
mAms.changeMagnificationMode(displayId, magnificationMode);
|
||||
}
|
||||
|
||||
private void disableFullScreenMagnificationIfNeeded(int displayId) {
|
||||
final FullScreenMagnificationController fullScreenMagnificationController =
|
||||
getFullScreenMagnificationController();
|
||||
@@ -514,7 +521,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
applyMagnificationModeLocked(mTargetMode);
|
||||
}
|
||||
updateMagnificationButton(mDisplayId, mTargetMode);
|
||||
mTransitionCallBack.onResult(success);
|
||||
mTransitionCallBack.onResult(mDisplayId, success);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,7 +546,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
setExpiredAndRemoveFromListLocked();
|
||||
applyMagnificationModeLocked(mCurrentMode);
|
||||
updateMagnificationButton(mDisplayId, mCurrentMode);
|
||||
mTransitionCallBack.onResult(true);
|
||||
mTransitionCallBack.onResult(mDisplayId, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,15 @@ public class WindowMagnificationManager implements
|
||||
* @param activated {@code true} if the magnification is activated, otherwise {@code false}.
|
||||
*/
|
||||
void onWindowMagnificationActivationState(int displayId, boolean activated);
|
||||
|
||||
/**
|
||||
* Called from {@link IWindowMagnificationConnection} to request changing the magnification
|
||||
* mode on the given display.
|
||||
*
|
||||
* @param displayId the logical display id
|
||||
* @param magnificationMode the target magnification mode
|
||||
*/
|
||||
void onChangeMagnificationMode(int displayId, int magnificationMode);
|
||||
}
|
||||
|
||||
private final Callback mCallback;
|
||||
@@ -535,7 +544,7 @@ public class WindowMagnificationManager implements
|
||||
FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK,
|
||||
"displayId=" + displayId + ";mode=" + magnificationMode);
|
||||
}
|
||||
//TODO: Uses this method to change the magnification mode on non-default display.
|
||||
mCallback.onChangeMagnificationMode(displayId, magnificationMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,13 +16,22 @@
|
||||
|
||||
package com.android.server.accessibility;
|
||||
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
|
||||
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
|
||||
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -38,17 +47,23 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.hardware.display.DisplayManagerGlobal;
|
||||
import android.os.IBinder;
|
||||
import android.provider.Settings;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.TestableContext;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayAdjustments;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.compatibility.common.util.TestUtils;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.accessibility.AccessibilityManagerService.AccessibilityDisplayListener;
|
||||
import com.android.server.accessibility.magnification.FullScreenMagnificationController;
|
||||
import com.android.server.accessibility.magnification.MagnificationController;
|
||||
import com.android.server.accessibility.magnification.WindowMagnificationManager;
|
||||
import com.android.server.accessibility.test.MessageCapturingHandler;
|
||||
@@ -58,10 +73,16 @@ import com.android.server.wm.WindowManagerInternal;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* APCT tests for {@link AccessibilityManagerService}.
|
||||
*/
|
||||
@@ -72,7 +93,8 @@ public class AccessibilityManagerServiceTest {
|
||||
private static final String INTENT_ACTION = "TESTACTION";
|
||||
private static final String DESCRIPTION = "description";
|
||||
private static final PendingIntent TEST_PENDING_INTENT = PendingIntent.getBroadcast(
|
||||
InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION), PendingIntent.FLAG_MUTABLE_UNAUDITED);
|
||||
InstrumentationRegistry.getTargetContext(), 0, new Intent(INTENT_ACTION),
|
||||
PendingIntent.FLAG_MUTABLE_UNAUDITED);
|
||||
private static final RemoteAction TEST_ACTION = new RemoteAction(
|
||||
Icon.createWithContentUri("content://test"),
|
||||
LABEL,
|
||||
@@ -81,11 +103,12 @@ public class AccessibilityManagerServiceTest {
|
||||
private static final AccessibilityAction NEW_ACCESSIBILITY_ACTION =
|
||||
new AccessibilityAction(ACTION_ID, LABEL);
|
||||
|
||||
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY + 1;
|
||||
|
||||
static final ComponentName COMPONENT_NAME = new ComponentName(
|
||||
"com.android.server.accessibility", "AccessibilityManagerServiceTest");
|
||||
static final int SERVICE_ID = 42;
|
||||
|
||||
@Mock private Context mMockContext;
|
||||
@Mock private AccessibilityServiceInfo mMockServiceInfo;
|
||||
@Mock private ResolveInfo mMockResolveInfo;
|
||||
@Mock private AbstractAccessibilityServiceConnection.SystemSupport mMockSystemSupport;
|
||||
@@ -102,12 +125,15 @@ public class AccessibilityManagerServiceTest {
|
||||
@Mock private IAccessibilityServiceClient mMockServiceClient;
|
||||
@Mock private WindowMagnificationManager mMockWindowMagnificationMgr;
|
||||
@Mock private MagnificationController mMockMagnificationController;
|
||||
@Mock private Resources mMockResources;
|
||||
@Mock private FullScreenMagnificationController mMockFullScreenMagnificationController;
|
||||
|
||||
private AccessibilityUserState mUserState;
|
||||
@Rule
|
||||
public final TestableContext mTestableContext = new TestableContext(
|
||||
getInstrumentation().getTargetContext(), null);
|
||||
|
||||
private MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
|
||||
private AccessibilityServiceConnection mAccessibilityServiceConnection;
|
||||
private AccessibilityInputFilter mInputFilter;
|
||||
private AccessibilityManagerService mA11yms;
|
||||
|
||||
@Before
|
||||
@@ -122,43 +148,54 @@ public class AccessibilityManagerServiceTest {
|
||||
ActivityTaskManagerInternal.class, mMockActivityTaskManagerInternal);
|
||||
LocalServices.addService(
|
||||
UserManagerInternal.class, mMockUserManagerInternal);
|
||||
mInputFilter = Mockito.mock(FakeInputFilter.class);
|
||||
|
||||
when(mMockMagnificationController.getWindowMagnificationMgr()).thenReturn(
|
||||
mMockWindowMagnificationMgr);
|
||||
when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
|
||||
mMockFullScreenMagnificationController);
|
||||
when(mMockWindowManagerService.getAccessibilityController()).thenReturn(
|
||||
mMockA11yController);
|
||||
when(mMockA11yController.isAccessibilityTracingEnabled()).thenReturn(false);
|
||||
when(mMockUserManagerInternal.isUserUnlockingOrUnlocked(anyInt())).thenReturn(true);
|
||||
|
||||
final ArrayList<Display> displays = new ArrayList<>();
|
||||
final Display defaultDisplay = new Display(DisplayManagerGlobal.getInstance(),
|
||||
Display.DEFAULT_DISPLAY, new DisplayInfo(),
|
||||
DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
final Display testDisplay = new Display(DisplayManagerGlobal.getInstance(), TEST_DISPLAY,
|
||||
new DisplayInfo(), DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
|
||||
displays.add(defaultDisplay);
|
||||
displays.add(testDisplay);
|
||||
when(mMockA11yDisplayListener.getValidDisplayList()).thenReturn(displays);
|
||||
|
||||
mA11yms = new AccessibilityManagerService(
|
||||
InstrumentationRegistry.getContext(),
|
||||
mMockPackageManager,
|
||||
mMockSecurityPolicy,
|
||||
mMockSystemActionPerformer,
|
||||
mMockA11yWindowManager,
|
||||
mMockA11yDisplayListener,
|
||||
mMockMagnificationController);
|
||||
mTestableContext,
|
||||
mMockPackageManager,
|
||||
mMockSecurityPolicy,
|
||||
mMockSystemActionPerformer,
|
||||
mMockA11yWindowManager,
|
||||
mMockA11yDisplayListener,
|
||||
mMockMagnificationController,
|
||||
mInputFilter);
|
||||
|
||||
mMockResources = mock(Resources.class);
|
||||
when(mMockContext.getResources()).thenReturn(mMockResources);
|
||||
|
||||
mUserState = new AccessibilityUserState(
|
||||
mA11yms.getCurrentUserIdLocked(), mMockContext, mA11yms);
|
||||
mA11yms.mUserStates.put(mA11yms.getCurrentUserIdLocked(), mUserState);
|
||||
final AccessibilityUserState userState = new AccessibilityUserState(
|
||||
mA11yms.getCurrentUserIdLocked(), mTestableContext, mA11yms);
|
||||
mA11yms.mUserStates.put(mA11yms.getCurrentUserIdLocked(), userState);
|
||||
}
|
||||
|
||||
private void setupAccessibilityServiceConnection() {
|
||||
when(mMockContext.getSystemService(Context.DISPLAY_SERVICE)).thenReturn(
|
||||
InstrumentationRegistry.getContext().getSystemService(
|
||||
Context.DISPLAY_SERVICE));
|
||||
|
||||
final AccessibilityUserState userState = mA11yms.mUserStates.get(
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
|
||||
mMockResolveInfo.serviceInfo = mock(ServiceInfo.class);
|
||||
mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
|
||||
|
||||
when(mMockBinder.queryLocalInterface(any())).thenReturn(mMockServiceClient);
|
||||
mTestableContext.addMockService(COMPONENT_NAME, mMockBinder);
|
||||
mAccessibilityServiceConnection = new AccessibilityServiceConnection(
|
||||
mUserState,
|
||||
mMockContext,
|
||||
userState,
|
||||
mTestableContext,
|
||||
COMPONENT_NAME,
|
||||
mMockServiceInfo,
|
||||
SERVICE_ID,
|
||||
@@ -172,7 +209,6 @@ public class AccessibilityManagerServiceTest {
|
||||
mMockA11yWindowManager,
|
||||
mMockActivityTaskManagerInternal);
|
||||
mAccessibilityServiceConnection.bindLocked();
|
||||
mAccessibilityServiceConnection.onServiceConnected(COMPONENT_NAME, mMockBinder);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@@ -220,7 +256,10 @@ public class AccessibilityManagerServiceTest {
|
||||
@Test
|
||||
public void testOnSystemActionsChanged() throws Exception {
|
||||
setupAccessibilityServiceConnection();
|
||||
mA11yms.notifySystemActionsChangedLocked(mUserState);
|
||||
final AccessibilityUserState userState = mA11yms.mUserStates.get(
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
|
||||
mA11yms.notifySystemActionsChangedLocked(userState);
|
||||
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
|
||||
verify(mMockServiceClient).onSystemActionsChanged();
|
||||
}
|
||||
@@ -228,24 +267,89 @@ public class AccessibilityManagerServiceTest {
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testOnMagnificationTransitionFailed_capabilitiesIsAll_fallBackToPreviousMode() {
|
||||
final AccessibilityUserState userState = mA11yms.mUserStates.get(
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
userState.setMagnificationCapabilitiesLocked(ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
|
||||
userState.setMagnificationModeLocked(Display.DEFAULT_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
|
||||
);
|
||||
|
||||
mA11yms.onMagnificationTransitionEndedLocked(Display.DEFAULT_DISPLAY, false);
|
||||
|
||||
Assert.assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
|
||||
userState.getMagnificationModeLocked(Display.DEFAULT_DISPLAY));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testOnMagnificationTransitionSuccess_capabilitiesIsAll_inputFilterRefreshMode() {
|
||||
final AccessibilityUserState userState = mA11yms.mUserStates.get(
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
userState.setMagnificationCapabilitiesLocked(
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
|
||||
userState.setMagnificationModeLocked(
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
|
||||
userState.setMagnificationModeLocked(Display.DEFAULT_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
|
||||
);
|
||||
|
||||
mA11yms.onMagnificationTransitionEndedLocked(false);
|
||||
mA11yms.onMagnificationTransitionEndedLocked(Display.DEFAULT_DISPLAY, true);
|
||||
|
||||
Assert.assertEquals(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
|
||||
userState.getMagnificationModeLocked());
|
||||
ArgumentCaptor<Display> displayCaptor = ArgumentCaptor.forClass(Display.class);
|
||||
verify(mInputFilter, timeout(100)).refreshMagnificationMode(displayCaptor.capture());
|
||||
Assert.assertEquals(Display.DEFAULT_DISPLAY, displayCaptor.getValue().getDisplayId());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testChangeMagnificationModeOnDefaultDisplay_capabilitiesIsAll_persistChangedMode()
|
||||
throws Exception {
|
||||
final AccessibilityUserState userState = mA11yms.mUserStates.get(
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
userState.setMagnificationCapabilitiesLocked(
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
|
||||
userState.setMagnificationModeLocked(Display.DEFAULT_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
|
||||
);
|
||||
|
||||
mA11yms.changeMagnificationMode(Display.DEFAULT_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
|
||||
TestUtils.waitUntil("magnification mode " + ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
|
||||
+ " is not persisted in setting", 1,
|
||||
() -> {
|
||||
final int userMode = Settings.Secure.getIntForUser(
|
||||
mTestableContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_NONE,
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
return userMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
|
||||
});
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testChangeMagnificationModeOnTestDisplay_capabilitiesIsAll_transitMode() {
|
||||
final AccessibilityUserState userState = mA11yms.mUserStates.get(
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
userState.setMagnificationCapabilitiesLocked(
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
|
||||
userState.setMagnificationModeLocked(TEST_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
|
||||
);
|
||||
|
||||
mA11yms.changeMagnificationMode(TEST_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
|
||||
verify(mMockMagnificationController).transitionMagnificationModeLocked(eq(TEST_DISPLAY),
|
||||
eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW), ArgumentMatchers.isNotNull());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@Test
|
||||
public void testOnClientChange_magnificationEnabledAndCapabilityAll_requestConnection() {
|
||||
mUserState.mAccessibilityShortcutKeyTargets.add(MAGNIFICATION_CONTROLLER_NAME);
|
||||
mUserState.setMagnificationCapabilitiesLocked(
|
||||
final AccessibilityUserState userState = mA11yms.mUserStates.get(
|
||||
mA11yms.getCurrentUserIdLocked());
|
||||
userState.mAccessibilityShortcutKeyTargets.add(MAGNIFICATION_CONTROLLER_NAME);
|
||||
userState.setMagnificationCapabilitiesLocked(
|
||||
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
|
||||
|
||||
// Invokes client change to trigger onUserStateChanged.
|
||||
@@ -265,4 +369,11 @@ public class AccessibilityManagerServiceTest {
|
||||
|
||||
verify(mMockWindowMagnificationMgr).requestConnection(true);
|
||||
}
|
||||
|
||||
public static class FakeInputFilter extends AccessibilityInputFilter {
|
||||
FakeInputFilter(Context context,
|
||||
AccessibilityManagerService service) {
|
||||
super(context, service);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import android.provider.Settings;
|
||||
import android.test.mock.MockContentResolver;
|
||||
import android.testing.DexmakerShareClassLoaderRule;
|
||||
import android.util.ArraySet;
|
||||
import android.view.Display;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
@@ -79,6 +80,8 @@ public class AccessibilityUserStateTest {
|
||||
|
||||
private static final int USER_ID = 42;
|
||||
|
||||
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
|
||||
|
||||
// Mock package-private class AccessibilityServiceConnection
|
||||
@Rule public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
|
||||
new DexmakerShareClassLoaderRule();
|
||||
@@ -143,7 +146,8 @@ public class AccessibilityUserStateTest {
|
||||
mUserState.setAutoclickEnabledLocked(true);
|
||||
mUserState.setUserNonInteractiveUiTimeoutLocked(30);
|
||||
mUserState.setUserInteractiveUiTimeoutLocked(30);
|
||||
mUserState.setMagnificationModeLocked(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
mUserState.setMagnificationModeLocked(TEST_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
mUserState.setFocusAppearanceLocked(20, Color.BLUE);
|
||||
|
||||
mUserState.onSwitchToAnotherUserLocked();
|
||||
@@ -165,7 +169,7 @@ public class AccessibilityUserStateTest {
|
||||
assertEquals(0, mUserState.getUserNonInteractiveUiTimeoutLocked());
|
||||
assertEquals(0, mUserState.getUserInteractiveUiTimeoutLocked());
|
||||
assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
|
||||
mUserState.getMagnificationModeLocked());
|
||||
mUserState.getMagnificationModeLocked(TEST_DISPLAY));
|
||||
assertEquals(mFocusStrokeWidthDefaultValue, mUserState.getFocusStrokeWidthLocked());
|
||||
assertEquals(mFocusColorDefaultValue, mUserState.getFocusColorLocked());
|
||||
}
|
||||
@@ -360,12 +364,13 @@ public class AccessibilityUserStateTest {
|
||||
@Test
|
||||
public void setWindowMagnificationMode_returnExpectedMagnificationMode() {
|
||||
assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
|
||||
mUserState.getMagnificationModeLocked());
|
||||
mUserState.getMagnificationModeLocked(TEST_DISPLAY));
|
||||
|
||||
mUserState.setMagnificationModeLocked(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
mUserState.setMagnificationModeLocked(TEST_DISPLAY,
|
||||
ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
|
||||
|
||||
assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
|
||||
mUserState.getMagnificationModeLocked());
|
||||
mUserState.getMagnificationModeLocked(TEST_DISPLAY));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -150,7 +150,7 @@ public class MagnificationControllerTest {
|
||||
MODE_WINDOW,
|
||||
mTransitionCallBack);
|
||||
|
||||
verify(mTransitionCallBack).onResult(true);
|
||||
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
|
||||
verify(mScreenMagnificationController, never()).reset(anyInt(),
|
||||
any(MagnificationAnimationCallback.class));
|
||||
verify(mMockConnection.getConnection(), never()).enableWindowMagnification(anyInt(),
|
||||
@@ -171,7 +171,7 @@ public class MagnificationControllerTest {
|
||||
mCallbackArgumentCaptor.capture());
|
||||
mCallbackArgumentCaptor.getValue().onResult(true);
|
||||
mMockConnection.invokeCallbacks();
|
||||
verify(mTransitionCallBack).onResult(true);
|
||||
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
|
||||
assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
|
||||
assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public class MagnificationControllerTest {
|
||||
mTransitionCallBack);
|
||||
|
||||
mMockConnection.invokeCallbacks();
|
||||
verify(mTransitionCallBack).onResult(true);
|
||||
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
|
||||
assertEquals(MAGNIFIED_CENTER_X, mWindowMagnificationManager.getCenterX(TEST_DISPLAY), 0);
|
||||
assertEquals(MAGNIFIED_CENTER_Y, mWindowMagnificationManager.getCenterY(TEST_DISPLAY), 0);
|
||||
}
|
||||
@@ -225,7 +225,7 @@ public class MagnificationControllerTest {
|
||||
verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY,
|
||||
DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
|
||||
true, MAGNIFICATION_GESTURE_HANDLER_ID);
|
||||
verify(mTransitionCallBack).onResult(true);
|
||||
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -245,7 +245,7 @@ public class MagnificationControllerTest {
|
||||
verify(mScreenMagnificationController).setScaleAndCenter(TEST_DISPLAY, DEFAULT_SCALE,
|
||||
magnificationBounds.exactCenterX(), magnificationBounds.exactCenterY(), true,
|
||||
MAGNIFICATION_GESTURE_HANDLER_ID);
|
||||
verify(mTransitionCallBack).onResult(true);
|
||||
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -265,7 +265,7 @@ public class MagnificationControllerTest {
|
||||
0);
|
||||
assertEquals(MAGNIFIED_CENTER_Y, mScreenMagnificationController.getCenterY(TEST_DISPLAY),
|
||||
0);
|
||||
verify(mTransitionCallBack).onResult(true);
|
||||
verify(mTransitionCallBack).onResult(TEST_DISPLAY, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -285,7 +285,7 @@ public class MagnificationControllerTest {
|
||||
verify(mScreenMagnificationController, never()).setScaleAndCenter(TEST_DISPLAY,
|
||||
DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
|
||||
true, MAGNIFICATION_GESTURE_HANDLER_ID);
|
||||
verify(mTransitionCallBack).onResult(false);
|
||||
verify(mTransitionCallBack).onResult(TEST_DISPLAY, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -595,6 +595,13 @@ public class MagnificationControllerTest {
|
||||
verify(mScaleProvider).onUserRemoved(SECOND_USER_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChangeMagnificationMode_delegateToService() {
|
||||
mMagnificationController.onChangeMagnificationMode(TEST_DISPLAY, MODE_WINDOW);
|
||||
|
||||
verify(mService).changeMagnificationMode(TEST_DISPLAY, MODE_WINDOW);
|
||||
}
|
||||
|
||||
private void setMagnificationEnabled(int mode) throws RemoteException {
|
||||
setMagnificationEnabled(mode, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user