Support following typing foucs in window mode [1/n].

There are 2 milestones in this feature.
1. Refactor the callbacks for Accessibility in WindowManagerInternal.
2. Implement this feature in such new architecture.

This CL is for the 1st milestone.

The goal of refactor:
When the window manager invokes callbacks which are related to
contextual changes affecting the screen magnification feature, it will
be handle by the MagnificationController first now. Then, it will
dispatch the events to the activated magnification controller such as
FullScreenMagnificationController or WindowMagnificationManager.

We use delegate design pattern to make MagnificationController as proxy.
It will assign a specific delegate when the activated controller is changed.
Then, it will dispatch the events from window manager to activated
magnification controller. Therefore, the activated magnification
controller will handle this event.

For now, we introduce WindowManagerEventDispatcher in
AccessibilityControllerInternalImpl to pass the callback events to
MagnificationController. However, AccessibilityControllerInternalImpl
would be refactored since it should have no nested class relation with
AccessibilityController.

Bug: 194668976
Test: atest FullScreenMagnificationControllerTest
	atest WindowMagnificationManagerTest
	atest MagnificationControllerTest
	atest CtsAccessibilityServiceTestCases
Change-Id: Ic4d87c48a15b9179afeda48132635adc8e86107c
This commit is contained in:
Daniel Hsieh
2021-12-08 15:18:37 +00:00
parent 0ee1df684e
commit 21a62f3c87
7 changed files with 300 additions and 81 deletions

View File

@@ -63,7 +63,8 @@ import java.util.Locale;
* magnification region. If a value is out of bounds, it will be adjusted to guarantee these
* constraints.
*/
public class FullScreenMagnificationController {
public class FullScreenMagnificationController implements
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {
private static final boolean DEBUG = false;
private static final String LOG_TAG = "FullScreenMagnificationController";
@@ -85,6 +86,8 @@ public class FullScreenMagnificationController {
@GuardedBy("mLock")
private final SparseArray<DisplayMagnification> mDisplays = new SparseArray<>(0);
private final Rect mTempRect = new Rect();
/**
* This class implements {@link WindowManagerInternal.MagnificationCallbacks} and holds
* magnification information per display.
@@ -727,6 +730,26 @@ public class FullScreenMagnificationController {
}
}
@Override
public void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
int bottom) {
synchronized (mLock) {
final DisplayMagnification display = mDisplays.get(displayId);
if (display == null) {
return;
}
if (!display.isMagnifying()) {
return;
}
final Rect magnifiedRegionBounds = mTempRect;
display.getMagnifiedFrameInContentCoordsLocked(magnifiedRegionBounds);
if (magnifiedRegionBounds.contains(left, top, right, bottom)) {
return;
}
display.onRectangleOnScreenRequested(left, top, right, bottom);
}
}
/**
* Remove the display magnification with given id.
*

View File

@@ -40,7 +40,9 @@ import android.view.accessibility.MagnificationAnimationCallback;
import com.android.internal.accessibility.util.AccessibilityStatsLogUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.wm.WindowManagerInternal;
/**
* Handles all magnification controllers initialization, generic interactions,
@@ -68,7 +70,8 @@ import com.android.server.accessibility.AccessibilityManagerService;
*/
public class MagnificationController implements WindowMagnificationManager.Callback,
MagnificationGestureHandler.Callback,
FullScreenMagnificationController.MagnificationInfoChangedCallback {
FullScreenMagnificationController.MagnificationInfoChangedCallback,
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {
private static final boolean DEBUG = false;
private static final String TAG = "MagnificationController";
@@ -96,6 +99,11 @@ public class MagnificationController implements WindowMagnificationManager.Callb
private long mWindowModeEnabledTime = 0;
private long mFullScreenModeEnabledTime = 0;
@GuardedBy("mLock")
@Nullable
private WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
mAccessibilityCallbacksDelegate;
/**
* A callback to inform the magnification transition result on the given display.
*/
@@ -115,6 +123,8 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mLock = lock;
mContext = context;
mScaleProvider = scaleProvider;
LocalServices.getService(WindowManagerInternal.class)
.getAccessibilityController().setUiChangesForAccessibilityCallbacks(this);
}
@VisibleForTesting
@@ -292,6 +302,37 @@ public class MagnificationController implements WindowMagnificationManager.Callb
return false;
}
@GuardedBy("mLock")
private void setActivatedModeAndSwitchDelegate(int mode) {
mActivatedMode = mode;
assignMagnificationWindowManagerDelegateByMode(mode);
}
private void assignMagnificationWindowManagerDelegateByMode(int mode) {
synchronized (mLock) {
if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN) {
mAccessibilityCallbacksDelegate = getFullScreenMagnificationController();
} else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
mAccessibilityCallbacksDelegate = getWindowMagnificationMgr();
} else {
mAccessibilityCallbacksDelegate = null;
}
}
}
@Override
public void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
int bottom) {
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
delegate;
synchronized (mLock) {
delegate = mAccessibilityCallbacksDelegate;
}
if (delegate != null) {
delegate.onRectangleOnScreenRequested(displayId, left, top, right, bottom);
}
}
@Override
public void onRequestMagnificationSpec(int displayId, int serviceId) {
final WindowMagnificationManager windowMagnificationManager;
@@ -314,7 +355,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mWindowModeEnabledTime = SystemClock.uptimeMillis();
synchronized (mLock) {
mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
mLastActivatedMode = mActivatedMode;
}
logMagnificationModeWithImeOnIfNeeded();
@@ -324,7 +365,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
SystemClock.uptimeMillis() - mWindowModeEnabledTime);
synchronized (mLock) {
mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_NONE);
}
}
updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
@@ -353,7 +394,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mFullScreenModeEnabledTime = SystemClock.uptimeMillis();
synchronized (mLock) {
mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
mLastActivatedMode = mActivatedMode;
}
logMagnificationModeWithImeOnIfNeeded();
@@ -363,7 +404,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
SystemClock.uptimeMillis() - mFullScreenModeEnabledTime);
synchronized (mLock) {
mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_NONE);
}
}
updateMagnificationButton(displayId, ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);

View File

@@ -45,6 +45,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.WindowManagerInternal;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -57,7 +58,8 @@ import java.lang.annotation.RetentionPolicy;
* {@link MagnificationScaleProvider#constrainScale(float)}
*/
public class WindowMagnificationManager implements
PanningScalingHandler.MagnificationDelegate {
PanningScalingHandler.MagnificationDelegate,
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks {
private static final boolean DBG = false;
@@ -263,6 +265,13 @@ public class WindowMagnificationManager implements
}
}
@Override
public void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
int bottom) {
// TODO(b/194668976): We will implement following typing focus in window mode after
// our refactor.
}
@Override
public boolean processScroll(int displayId, float distanceX, float distanceY) {
moveWindowMagnification(displayId, -distanceX, -distanceY);

View File

@@ -98,6 +98,7 @@ import android.view.animation.Interpolator;
import com.android.internal.R;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.TraceBuffer;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.WindowManagerInternal.AccessibilityControllerInternal;
@@ -277,20 +278,6 @@ final class AccessibilityController {
}
}
void onRectangleOnScreenRequested(int displayId, Rect rectangle) {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(
TAG + ".onRectangleOnScreenRequested",
FLAGS_MAGNIFICATION_CALLBACK,
"displayId=" + displayId + "; rectangle={" + rectangle + "}");
}
final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
if (displayMagnifier != null) {
displayMagnifier.onRectangleOnScreenRequested(rectangle);
}
// Not relevant for the window observer.
}
void onWindowLayersChanged(int displayId) {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK
| FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK)) {
@@ -634,31 +621,6 @@ final class AccessibilityController {
return mForceShowMagnifiableBounds;
}
void onRectangleOnScreenRequested(Rect rectangle) {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(LOG_TAG + ".onRectangleOnScreenRequested",
FLAGS_MAGNIFICATION_CALLBACK, "rectangle={" + rectangle + "}");
}
if (DEBUG_RECTANGLE_REQUESTED) {
Slog.i(LOG_TAG, "Rectangle on screen requested: " + rectangle);
}
if (!mMagnifedViewport.isMagnifying()) {
return;
}
Rect magnifiedRegionBounds = mTempRect2;
mMagnifedViewport.getMagnifiedFrameInContentCoords(magnifiedRegionBounds);
if (magnifiedRegionBounds.contains(rectangle)) {
return;
}
SomeArgs args = SomeArgs.obtain();
args.argi1 = rectangle.left;
args.argi2 = rectangle.top;
args.argi3 = rectangle.right;
args.argi4 = rectangle.bottom;
mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED,
args).sendToTarget();
}
void onWindowLayersChanged() {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(
@@ -1352,7 +1314,6 @@ final class AccessibilityController {
private class MyHandler extends Handler {
public static final int MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED = 1;
public static final int MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 2;
public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3;
public static final int MESSAGE_NOTIFY_DISPLAY_SIZE_CHANGED = 4;
public static final int MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED = 5;
@@ -1372,16 +1333,6 @@ final class AccessibilityController {
magnifiedBounds.recycle();
} break;
case MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {
SomeArgs args = (SomeArgs) message.obj;
final int left = args.argi1;
final int top = args.argi2;
final int right = args.argi3;
final int bottom = args.argi4;
mCallbacks.onRectangleOnScreenRequested(left, top, right, bottom);
args.recycle();
} break;
case MESSAGE_NOTIFY_USER_CONTEXT_CHANGED: {
mCallbacks.onUserContextChanged();
} break;
@@ -1902,7 +1853,7 @@ final class AccessibilityController {
}
}
private static final class AccessibilityControllerInternalImpl
static final class AccessibilityControllerInternalImpl
implements AccessibilityControllerInternal {
private static AccessibilityControllerInternalImpl sInstance;
@@ -1917,8 +1868,11 @@ final class AccessibilityController {
private final AccessibilityTracing mTracing;
private volatile long mEnabledTracingFlags;
private UiChangesForAccessibilityCallbacksDispatcher mCallbacksDispatcher;
private final Looper mLooper;
private AccessibilityControllerInternalImpl(WindowManagerService service) {
mLooper = service.mH.getLooper();
mTracing = AccessibilityTracing.getInstance(service);
mEnabledTracingFlags = 0L;
}
@@ -1972,6 +1926,90 @@ final class AccessibilityController {
mTracing.logState(where, loggingTypes, callingParams, a11yDump, callingUid, callStack,
timeStamp, processId, threadId, ignoreStackEntries);
}
@Override
public void setUiChangesForAccessibilityCallbacks(
UiChangesForAccessibilityCallbacks callbacks) {
if (isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
logTrace(
TAG + ".setAccessibilityWindowManagerCallbacks",
FLAGS_MAGNIFICATION_CALLBACK,
"callbacks={" + callbacks + "}");
}
if (callbacks != null) {
if (mCallbacksDispatcher != null) {
throw new IllegalStateException("Accessibility window manager callback already "
+ "set!");
}
mCallbacksDispatcher =
new UiChangesForAccessibilityCallbacksDispatcher(this, mLooper,
callbacks);
} else {
if (mCallbacksDispatcher == null) {
throw new IllegalStateException("Accessibility window manager callback already "
+ "cleared!");
}
mCallbacksDispatcher = null;
}
}
public boolean hasWindowManagerEventDispatcher() {
if (isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK
| FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK)) {
logTrace(TAG + ".hasCallbacks",
FLAGS_MAGNIFICATION_CALLBACK | FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK);
}
return mCallbacksDispatcher != null;
}
public void onRectangleOnScreenRequested(int displayId, Rect rectangle) {
if (isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
logTrace(
TAG + ".onRectangleOnScreenRequested",
FLAGS_MAGNIFICATION_CALLBACK,
"rectangle={" + rectangle + "}");
}
if (mCallbacksDispatcher != null) {
mCallbacksDispatcher.onRectangleOnScreenRequested(displayId, rectangle);
}
}
private static final class UiChangesForAccessibilityCallbacksDispatcher {
private static final String LOG_TAG = TAG_WITH_CLASS_NAME
? "WindowManagerEventDispatcher" : TAG_WM;
private static final boolean DEBUG_RECTANGLE_REQUESTED = false;
private final AccessibilityControllerInternalImpl mAccessibilityTracing;
@NonNull
private final UiChangesForAccessibilityCallbacks mCallbacks;
private final Handler mHandler;
UiChangesForAccessibilityCallbacksDispatcher(
AccessibilityControllerInternalImpl accessibilityControllerInternal,
Looper looper, @NonNull UiChangesForAccessibilityCallbacks callbacks) {
mAccessibilityTracing = accessibilityControllerInternal;
mCallbacks = callbacks;
mHandler = new Handler(looper);
}
void onRectangleOnScreenRequested(int displayId, Rect rectangle) {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(LOG_TAG + ".onRectangleOnScreenRequested",
FLAGS_MAGNIFICATION_CALLBACK, "rectangle={" + rectangle + "}");
}
if (DEBUG_RECTANGLE_REQUESTED) {
Slog.i(LOG_TAG, "Rectangle on screen requested: " + rectangle);
}
final Message m = PooledLambda.obtainMessage(
mCallbacks::onRectangleOnScreenRequested, displayId, rectangle.left,
rectangle.top, rectangle.right, rectangle.bottom);
mHandler.sendMessage(m);
}
}
}
private static final class AccessibilityTracing {

View File

@@ -104,6 +104,32 @@ public abstract class WindowManagerInternal {
void logTrace(String where, long loggingTypeFlags, String callingParams,
byte[] a11yDump, int callingUid, StackTraceElement[] callStack, long timeStamp,
int processId, long threadId, Set<String> ignoreStackEntries);
/**
* Set by the accessibility related modules which want to listen the event dispatched from
* window manager. Accessibility modules can use these callbacks to handle some display
* manipulations.
* @param callbacks The callbacks to invoke.
*/
void setUiChangesForAccessibilityCallbacks(UiChangesForAccessibilityCallbacks callbacks);
/**
* This interface is used by window manager to dispatch some ui change events which may
* affect the screen accessibility features.
*/
interface UiChangesForAccessibilityCallbacks {
/**
* Called when an application requests a rectangle focus on the screen.
*
* @param displayId The logical display id
* @param left The rectangle left.
* @param top The rectangle top.
* @param right The rectangle right.
* @param bottom The rectangle bottom.
*/
void onRectangleOnScreenRequested(int displayId, int left, int top, int right,
int bottom);
}
}
/**

View File

@@ -2143,11 +2143,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
final AccessibilityController.AccessibilityControllerInternalImpl a11yControllerInternal =
AccessibilityController.getAccessibilityControllerInternal(this);
synchronized (mGlobalLock) {
if (mAccessibilityController.hasCallbacks()) {
if (a11yControllerInternal.hasWindowManagerEventDispatcher()) {
WindowState window = mWindowMap.get(token);
if (window != null) {
mAccessibilityController.onRectangleOnScreenRequested(
a11yControllerInternal.onRectangleOnScreenRequested(
window.getDisplayId(), rectangle);
}
}

View File

@@ -55,8 +55,10 @@ import android.view.accessibility.MagnificationAnimationCallback;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.wm.WindowManagerInternal;
import org.junit.After;
import org.junit.Before;
@@ -79,6 +81,7 @@ public class MagnificationControllerTest {
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
private static final int TEST_SERVICE_ID = 1;
private static final Region MAGNIFICATION_REGION = new Region(0, 0, 500, 600);
private static final Rect TEST_RECT = new Rect(0, 50, 100, 51);
private static final float MAGNIFIED_CENTER_X = 100;
private static final float MAGNIFIED_CENTER_Y = 200;
private static final float DEFAULT_SCALE = 3f;
@@ -108,6 +111,11 @@ public class MagnificationControllerTest {
private MagnificationController mMagnificationController;
private FullScreenMagnificationControllerStubber mScreenMagnificationControllerStubber;
@Mock
private WindowManagerInternal mMockWindowManagerInternal;
@Mock
private WindowManagerInternal.AccessibilityControllerInternal mMockA11yController;
// To mock package-private class
@Rule
public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
@@ -117,6 +125,12 @@ public class MagnificationControllerTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
FakeSettingsProvider.clearSettingsProvider();
LocalServices.removeServiceForTest(WindowManagerInternal.class);
LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
when(mMockWindowManagerInternal.getAccessibilityController()).thenReturn(
mMockA11yController);
mMockResolver = new MockContentResolver();
mMockResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
when(mContext.getContentResolver()).thenReturn(mMockResolver);
@@ -132,8 +146,8 @@ public class MagnificationControllerTest {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mScreenMagnificationControllerStubber = new FullScreenMagnificationControllerStubber(
mScreenMagnificationController);
mMagnificationController = spy(new MagnificationController(mService, new Object(), mContext,
mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider));
mMagnificationController = new MagnificationController(mService, new Object(), mContext,
mScreenMagnificationController, mWindowMagnificationManager, mScaleProvider);
mMagnificationController.setMagnificationCapabilities(
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
@@ -439,16 +453,65 @@ public class MagnificationControllerTest {
@Test
public void onWindowMagnificationActivationState_windowActivated_logWindowDuration() {
mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
MagnificationController spyController = spy(mMagnificationController);
spyController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, false);
spyController.onWindowMagnificationActivationState(TEST_DISPLAY, false);
verify(mMagnificationController).logMagnificationUsageState(
verify(spyController).logMagnificationUsageState(
eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW), anyLong());
}
@Test
public void onWinodwModeActivated_fullScreenIsActivatedByExternal_fullScreenIsDisabled() {
public void onRectangleOnScreenRequested_fullScreenIsActivated_fullScreenDispatchEvent() {
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY,
true);
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
callbacks = getUiChangesForAccessibilityCallbacks();
callbacks.onRectangleOnScreenRequested(TEST_DISPLAY,
TEST_RECT.left, TEST_RECT.top, TEST_RECT.right, TEST_RECT.bottom);
verify(mScreenMagnificationController).onRectangleOnScreenRequested(eq(TEST_DISPLAY),
eq(TEST_RECT.left), eq(TEST_RECT.top), eq(TEST_RECT.right), eq(TEST_RECT.bottom));
verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
}
@Test
public void onRectangleOnScreenRequested_fullScreenIsInactivated_noneDispatchEvent() {
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY,
true);
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY,
false);
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
callbacks = getUiChangesForAccessibilityCallbacks();
callbacks.onRectangleOnScreenRequested(TEST_DISPLAY,
TEST_RECT.left, TEST_RECT.top, TEST_RECT.right, TEST_RECT.bottom);
verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
}
@Test
public void onRectangleOnScreenRequested_NoneIsActivated_noneDispatchEvent() {
WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
callbacks = getUiChangesForAccessibilityCallbacks();
callbacks.onRectangleOnScreenRequested(TEST_DISPLAY,
TEST_RECT.left, TEST_RECT.top, TEST_RECT.right, TEST_RECT.bottom);
verify(mScreenMagnificationController, never()).onRectangleOnScreenRequested(
eq(TEST_DISPLAY), anyInt(), anyInt(), anyInt(), anyInt());
verify(mWindowMagnificationManager, never()).onRectangleOnScreenRequested(anyInt(),
anyInt(), anyInt(), anyInt(), anyInt());
}
@Test
public void onWindowModeActivated_fullScreenIsActivatedByExternal_fullScreenIsDisabled() {
mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY,
DEFAULT_SCALE, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y,
true, TEST_SERVICE_ID);
@@ -461,11 +524,12 @@ public class MagnificationControllerTest {
@Test
public void
onFullScreenMagnificationActivationState_fullScreenActivated_logFullScreenDuration() {
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
MagnificationController spyController = spy(mMagnificationController);
spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, false);
spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, false);
verify(mMagnificationController).logMagnificationUsageState(
verify(spyController).logMagnificationUsageState(
eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN), anyLong());
}
@@ -627,43 +691,48 @@ public class MagnificationControllerTest {
@Test
public void imeWindowStateShown_windowMagnifying_logWindowMode() {
mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
MagnificationController spyController = spy(mMagnificationController);
spyController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
mMagnificationController.onImeWindowVisibilityChanged(true);
spyController.onImeWindowVisibilityChanged(true);
verify(mMagnificationController).logMagnificationModeWithIme(
verify(spyController).logMagnificationModeWithIme(
eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
}
@Test
public void imeWindowStateShown_fullScreenMagnifying_logFullScreenMode() {
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
MagnificationController spyController = spy(mMagnificationController);
spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
mMagnificationController.onImeWindowVisibilityChanged(true);
spyController.onImeWindowVisibilityChanged(true);
verify(mMagnificationController).logMagnificationModeWithIme(
verify(spyController).logMagnificationModeWithIme(
eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
}
@Test
public void imeWindowStateShown_noMagnifying_noLogAnyMode() {
mMagnificationController.onImeWindowVisibilityChanged(true);
MagnificationController spyController = spy(mMagnificationController);
spyController.onImeWindowVisibilityChanged(true);
verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
verify(spyController, never()).logMagnificationModeWithIme(anyInt());
}
@Test
public void imeWindowStateHidden_windowMagnifying_noLogAnyMode() {
mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
MagnificationController spyController = spy(mMagnificationController);
spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
verify(spyController, never()).logMagnificationModeWithIme(anyInt());
}
@Test
public void imeWindowStateHidden_fullScreenMagnifying_noLogAnyMode() {
mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
MagnificationController spyController = spy(mMagnificationController);
spyController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
verify(mMagnificationController, never()).logMagnificationModeWithIme(anyInt());
verify(spyController, never()).logMagnificationModeWithIme(anyInt());
}
@Test
@@ -718,6 +787,17 @@ public class MagnificationControllerTest {
MAGNIFIED_CENTER_X).setCenterY(MAGNIFIED_CENTER_Y).build();
}
private WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks
getUiChangesForAccessibilityCallbacks() {
ArgumentCaptor<WindowManagerInternal.AccessibilityControllerInternal
.UiChangesForAccessibilityCallbacks> captor = ArgumentCaptor.forClass(
WindowManagerInternal.AccessibilityControllerInternal
.UiChangesForAccessibilityCallbacks.class);
verify(mMockWindowManagerInternal.getAccessibilityController())
.setUiChangesForAccessibilityCallbacks(captor.capture());
return captor.getValue();
}
/**
* Stubs public methods to simulate the real beahviours.
*/