Merge "Notifies window magnifcation changes for AccessibilityService (1/n)"

This commit is contained in:
Minche Li
2022-01-07 01:00:27 +00:00
committed by Android (Google) Code Review
13 changed files with 231 additions and 78 deletions

View File

@@ -3143,6 +3143,7 @@ package android.accessibilityservice {
public static interface AccessibilityService.MagnificationController.OnMagnificationChangedListener {
method public void onMagnificationChanged(@NonNull android.accessibilityservice.AccessibilityService.MagnificationController, @NonNull android.graphics.Region, float, float, float);
method public default void onMagnificationChanged(@NonNull android.accessibilityservice.AccessibilityService.MagnificationController, @NonNull android.graphics.Region, @NonNull android.accessibilityservice.MagnificationConfig);
}
public static final class AccessibilityService.ScreenshotResult {

View File

@@ -588,7 +588,7 @@ public abstract class AccessibilityService extends Service {
boolean onKeyEvent(KeyEvent event);
/** Magnification changed callbacks for different displays */
void onMagnificationChanged(int displayId, @NonNull Region region,
float scale, float centerX, float centerY);
MagnificationConfig config);
/** Callbacks for receiving motion events. */
void onMotionEvent(MotionEvent event);
/** Callback for tuch state changes. */
@@ -1183,14 +1183,14 @@ public abstract class AccessibilityService extends Service {
}
}
private void onMagnificationChanged(int displayId, @NonNull Region region, float scale,
float centerX, float centerY) {
private void onMagnificationChanged(int displayId, @NonNull Region region,
MagnificationConfig config) {
MagnificationController controller;
synchronized (mLock) {
controller = mMagnificationControllers.get(displayId);
}
if (controller != null) {
controller.dispatchMagnificationChanged(region, scale, centerX, centerY);
controller.dispatchMagnificationChanged(region, config);
}
}
@@ -1328,8 +1328,8 @@ public abstract class AccessibilityService extends Service {
* Dispatches magnification changes to any registered listeners. This
* should be called on the service's main thread.
*/
void dispatchMagnificationChanged(final @NonNull Region region, final float scale,
final float centerX, final float centerY) {
void dispatchMagnificationChanged(final @NonNull Region region,
final MagnificationConfig config) {
final ArrayMap<OnMagnificationChangedListener, Handler> entries;
synchronized (mLock) {
if (mListeners == null || mListeners.isEmpty()) {
@@ -1348,16 +1348,13 @@ public abstract class AccessibilityService extends Service {
final OnMagnificationChangedListener listener = entries.keyAt(i);
final Handler handler = entries.valueAt(i);
if (handler != null) {
handler.post(new Runnable() {
@Override
public void run() {
listener.onMagnificationChanged(MagnificationController.this,
region, scale, centerX, centerY);
}
handler.post(() -> {
listener.onMagnificationChanged(MagnificationController.this,
region, config);
});
} else {
// We're already on the main thread, just run the listener.
listener.onMagnificationChanged(this, region, scale, centerX, centerY);
listener.onMagnificationChanged(this, region, config);
}
}
}
@@ -1665,6 +1662,10 @@ public abstract class AccessibilityService extends Service {
public interface OnMagnificationChangedListener {
/**
* Called when the magnified region, scale, or center changes.
* <p>
* <strong>Note:</strong> This legacy callback notifies only full-screen
* magnification change.
* </p>
*
* @param controller the magnification controller
* @param region the magnification region
@@ -1676,6 +1677,38 @@ public abstract class AccessibilityService extends Service {
*/
void onMagnificationChanged(@NonNull MagnificationController controller,
@NonNull Region region, float scale, float centerX, float centerY);
/**
* Called when the magnified region, mode, scale, or center changes of
* all magnification modes.
* <p>
* <strong>Note:</strong> This method can be overridden to listen to the
* magnification changes of all magnification modes then the legacy callback
* would not receive the notifications.
* Skipping calling super when overriding this method results in
* {@link #onMagnificationChanged(MagnificationController, Region, float, float, float)}
* not getting called.
* </p>
*
* @param controller the magnification controller
* @param region the magnification region
* If the config mode is
* {@link MagnificationConfig#MAGNIFICATION_MODE_FULLSCREEN},
* it is the region of the screen currently active for magnification.
* that is the same region as {@link #getMagnificationRegion()}.
* If the config mode is
* {@link MagnificationConfig#MAGNIFICATION_MODE_WINDOW},
* it is the region of screen projected on the magnification window.
* @param config The magnification config. That has the controlling magnification
* mode, the new scale and the new screen-relative center position
*/
default void onMagnificationChanged(@NonNull MagnificationController controller,
@NonNull Region region, @NonNull MagnificationConfig config) {
if (config.getMode() == MAGNIFICATION_MODE_FULLSCREEN) {
onMagnificationChanged(controller, region,
config.getScale(), config.getCenterX(), config.getCenterY());
}
}
}
}
@@ -2449,9 +2482,8 @@ public abstract class AccessibilityService extends Service {
@Override
public void onMagnificationChanged(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
AccessibilityService.this.onMagnificationChanged(displayId, region, scale,
centerX, centerY);
MagnificationConfig config) {
AccessibilityService.this.onMagnificationChanged(displayId, region, config);
}
@Override
@@ -2575,12 +2607,10 @@ public abstract class AccessibilityService extends Service {
/** Magnification changed callbacks for different displays */
public void onMagnificationChanged(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
MagnificationConfig config) {
final SomeArgs args = SomeArgs.obtain();
args.arg1 = region;
args.arg2 = scale;
args.arg3 = centerX;
args.arg4 = centerY;
args.arg2 = config;
args.argi1 = displayId;
final Message message = mCaller.obtainMessageO(DO_ON_MAGNIFICATION_CHANGED, args);
@@ -2739,13 +2769,10 @@ public abstract class AccessibilityService extends Service {
if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
final SomeArgs args = (SomeArgs) message.obj;
final Region region = (Region) args.arg1;
final float scale = (float) args.arg2;
final float centerX = (float) args.arg3;
final float centerY = (float) args.arg4;
final MagnificationConfig config = (MagnificationConfig) args.arg2;
final int displayId = args.argi1;
args.recycle();
mCallback.onMagnificationChanged(displayId, region, scale,
centerX, centerY);
mCallback.onMagnificationChanged(displayId, region, config);
}
return;
}

View File

@@ -21,6 +21,7 @@ import android.graphics.Region;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityWindowInfo;
import android.accessibilityservice.AccessibilityGestureEvent;
import android.accessibilityservice.MagnificationConfig;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -43,7 +44,7 @@ import android.view.MotionEvent;
void onKeyEvent(in KeyEvent event, int sequence);
void onMagnificationChanged(int displayId, in Region region, float scale, float centerX, float centerY);
void onMagnificationChanged(int displayId, in Region region, in MagnificationConfig config);
void onMotionEvent(in MotionEvent event);

View File

@@ -22,6 +22,7 @@ import android.accessibilityservice.AccessibilityService.IAccessibilityServiceCl
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.IAccessibilityServiceConnection;
import android.accessibilityservice.MagnificationConfig;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1581,7 +1582,7 @@ public final class UiAutomation {
@Override
public void onMagnificationChanged(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
MagnificationConfig config) {
/* do nothing */
}

View File

@@ -252,7 +252,12 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
mMagnificationFrame.height());
mTransaction.setGeometry(mMirrorSurface, mSourceBounds, mTmpRect,
Surface.ROTATION_0).apply();
mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId, mSourceBounds);
// Notify source bounds change when the magnifier is not animating.
if (!mAnimationController.isAnimating()) {
mWindowMagnifierCallback.onSourceBoundsChanged(mDisplayId,
mSourceBounds);
}
}
};
mUpdateStateDescriptionRunnable = () -> {
@@ -596,7 +601,6 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
private void modifyWindowMagnification(SurfaceControl.Transaction t) {
mSfVsyncFrameProvider.postFrameCallback(mMirrorViewGeometryVsyncCallback);
updateMirrorViewLayout();
}
/**
@@ -800,7 +804,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
* are as same as current values, or the transition is interrupted
* due to the new transition request.
*/
void enableWindowMagnification(float scale, float centerX, float centerY,
public void enableWindowMagnification(float scale, float centerX, float centerY,
float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY,
@Nullable IRemoteMagnificationAnimationCallback animationCallback) {
mAnimationController.enableWindowMagnification(scale, centerX, centerY,

View File

@@ -34,6 +34,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
@@ -60,6 +61,7 @@ import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
@@ -75,6 +77,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -89,8 +92,6 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
@Mock
private Handler mHandler;
@Mock
private WindowMagnificationAnimationController mWindowMagnificationAnimationController;
@Mock
private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
@Mock
private MirrorWindowControl mMirrorWindowControl;
@@ -101,6 +102,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
private TestableWindowManager mWindowManager;
private SysUiState mSysUiState = new SysUiState();
private Resources mResources;
private WindowMagnificationAnimationController mWindowMagnificationAnimationController;
private WindowMagnificationController mWindowMagnificationController;
private Instrumentation mInstrumentation;
@@ -125,10 +127,11 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
return null;
}).when(mHandler).post(
any(Runnable.class));
mSysUiState.addCallback(Mockito.mock(SysUiState.SysUiStateCallback.class));
mResources = getContext().getOrCreateTestableResources().getResources();
mWindowMagnificationAnimationController = new WindowMagnificationAnimationController(
mContext);
mWindowMagnificationController = new WindowMagnificationController(mContext,
mHandler, mWindowMagnificationAnimationController, mSfVsyncFrameProvider,
mMirrorWindowControl, mTransaction, mWindowMagnifierCallback, mSysUiState);
@@ -156,6 +159,52 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
eq(mContext.getDisplayId()), any(Rect.class));
}
@Test
public void enableWindowMagnification_notifySourceBoundsChanged() {
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
Float.NaN, /* magnificationFrameOffsetRatioX= */ 0,
/* magnificationFrameOffsetRatioY= */ 0, null);
});
// Waits for the surface created
verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS)).onSourceBoundsChanged(
(eq(mContext.getDisplayId())), any());
}
@Test
public void enableWindowMagnification_withAnimation_schedulesFrame() {
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.enableWindowMagnification(2.0f, 10,
10, /* magnificationFrameOffsetRatioX= */ 0,
/* magnificationFrameOffsetRatioY= */ 0,
Mockito.mock(IRemoteMagnificationAnimationCallback.class));
});
verify(mSfVsyncFrameProvider,
timeout(LAYOUT_CHANGE_TIMEOUT_MS).atLeast(2)).postFrameCallback(any());
}
@Test
public void moveWindowMagnifier_enabled_notifySourceBoundsChanged() {
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
Float.NaN, 0, 0, null);
});
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.moveWindowMagnifier(10, 10);
});
final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
verify(mWindowMagnifierCallback, atLeast(2)).onSourceBoundsChanged(
(eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
assertEquals(mWindowMagnificationController.getCenterX(),
sourceBoundsCaptor.getValue().exactCenterX(), 0);
assertEquals(mWindowMagnificationController.getCenterY(),
sourceBoundsCaptor.getValue().exactCenterY(), 0);
}
@Test
public void enableWindowMagnification_systemGestureExclusionRectsIsSet() {
mInstrumentation.runOnMainSync(() -> {

View File

@@ -1542,9 +1542,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
}
public void notifyMagnificationChangedLocked(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
@NonNull MagnificationConfig config) {
mInvocationHandler
.notifyMagnificationChangedLocked(displayId, region, scale, centerX, centerY);
.notifyMagnificationChangedLocked(displayId, region, config);
}
public void notifySoftKeyboardShowModeChangedLocked(int showState) {
@@ -1564,15 +1564,15 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
* state of magnification has changed.
*/
private void notifyMagnificationChangedInternal(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
@NonNull MagnificationConfig config) {
final IAccessibilityServiceClient listener = getServiceInterfaceSafely();
if (listener != null) {
try {
if (svcClientTracingEnabled()) {
logTraceSvcClient("onMagnificationChanged", displayId + ", " + region + ", "
+ scale + ", " + centerX + ", " + centerY);
+ config.toString());
}
listener.onMagnificationChanged(displayId, region, scale, centerX, centerY);
listener.onMagnificationChanged(displayId, region, config);
} catch (RemoteException re) {
Slog.e(LOG_TAG, "Error sending magnification changes to " + mService, re);
}
@@ -1899,11 +1899,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
case MSG_ON_MAGNIFICATION_CHANGED: {
final SomeArgs args = (SomeArgs) message.obj;
final Region region = (Region) args.arg1;
final float scale = (float) args.arg2;
final float centerX = (float) args.arg3;
final float centerY = (float) args.arg4;
final MagnificationConfig config = (MagnificationConfig) args.arg2;
final int displayId = args.argi1;
notifyMagnificationChangedInternal(displayId, region, scale, centerX, centerY);
notifyMagnificationChangedInternal(displayId, region, config);
args.recycle();
} break;
@@ -1932,7 +1930,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
}
public void notifyMagnificationChangedLocked(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
@NonNull MagnificationConfig config) {
synchronized (mLock) {
if (mMagnificationCallbackState.get(displayId) == null) {
return;
@@ -1941,9 +1939,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
final SomeArgs args = SomeArgs.obtain();
args.arg1 = region;
args.arg2 = scale;
args.arg3 = centerX;
args.arg4 = centerY;
args.arg2 = config;
args.argi1 = displayId;
final Message msg = obtainMessage(MSG_ON_MAGNIFICATION_CHANGED, args);

View File

@@ -44,6 +44,7 @@ import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityShortcutInfo;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.accessibilityservice.MagnificationConfig;
import android.accessibilityservice.TouchInteractionController;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1301,18 +1302,22 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
* Called by the MagnificationController when the state of display
* magnification changes.
*
* @param displayId The logical display id.
* <p>
* It can notify window magnification change if the service supports controlling all the
* magnification mode.
* </p>
*
* @param displayId The logical display id
* @param region the new magnified region, may be empty if
* magnification is not enabled (e.g. scale is 1)
* @param scale the new scale
* @param centerX the new screen-relative center X coordinate
* @param centerY the new screen-relative center Y coordinate
* @param config The magnification config. That has magnification mode, the new scale and the
* new screen-relative center position
*/
public void notifyMagnificationChanged(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
@NonNull MagnificationConfig config) {
synchronized (mLock) {
notifyClearAccessibilityCacheLocked();
notifyMagnificationChangedLocked(displayId, region, scale, centerX, centerY);
notifyMagnificationChangedLocked(displayId, region, config);
}
}
@@ -1613,11 +1618,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
private void notifyMagnificationChangedLocked(int displayId, @NonNull Region region,
float scale, float centerX, float centerY) {
@NonNull MagnificationConfig config) {
final AccessibilityUserState state = getCurrentUserStateLocked();
for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
final AccessibilityServiceConnection service = state.mBoundServices.get(i);
service.notifyMagnificationChangedLocked(displayId, region, scale, centerX, centerY);
service.notifyMagnificationChangedLocked(displayId, region, config);
}
}

View File

@@ -17,10 +17,12 @@
package com.android.server.accessibility.magnification;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL;
import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN;
import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK;
import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID;
import android.accessibilityservice.MagnificationConfig;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
@@ -363,9 +365,16 @@ public class FullScreenMagnificationController implements
return mIdOfLastServiceToMagnify;
}
@GuardedBy("mLock")
void onMagnificationChangedLocked() {
mControllerCtx.getAms().notifyMagnificationChanged(mDisplayId, mMagnificationRegion,
getScale(), getCenterX(), getCenterY());
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(MAGNIFICATION_MODE_FULLSCREEN)
.setScale(getScale())
.setCenterX(getCenterX())
.setCenterY(getCenterY()).build();
mControllerCtx.getAms().notifyMagnificationChanged(mDisplayId,
mMagnificationRegion,
config);
if (mUnregisterPending && !isMagnifying()) {
unregister(mDeleteAfterUnregister);
}

View File

@@ -16,6 +16,7 @@
package com.android.server.accessibility.magnification;
import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW;
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;
@@ -379,6 +380,16 @@ public class MagnificationController implements WindowMagnificationManager.Callb
mAms.changeMagnificationMode(displayId, magnificationMode);
}
@Override
public void onSourceBoundsChanged(int displayId, Rect bounds) {
final MagnificationConfig config = new MagnificationConfig.Builder()
.setMode(MAGNIFICATION_MODE_WINDOW)
.setScale(mScaleProvider.getScale(displayId))
.setCenterX(bounds.exactCenterX())
.setCenterY(bounds.exactCenterY()).build();
mAms.notifyMagnificationChanged(displayId, new Region(bounds), config);
}
private void disableFullScreenMagnificationIfNeeded(int displayId) {
final FullScreenMagnificationController fullScreenMagnificationController =
getFullScreenMagnificationController();

View File

@@ -138,6 +138,14 @@ public class WindowMagnificationManager implements
*/
void onWindowMagnificationActivationState(int displayId, boolean activated);
/**
* Called when the magnification source bounds are changed.
*
* @param displayId The logical display id.
* @param bounds The magnified source bounds on the display.
*/
void onSourceBoundsChanged(int displayId, Rect bounds);
/**
* Called from {@link IWindowMagnificationConnection} to request changing the magnification
* mode on the given display.
@@ -689,6 +697,7 @@ public class WindowMagnificationManager implements
}
magnifier.onSourceBoundsChanged(sourceBounds);
}
mCallback.onSourceBoundsChanged(displayId, sourceBounds);
}
@Override

View File

@@ -16,6 +16,8 @@
package com.android.server.accessibility.magnification;
import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN;
import static com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback;
import static org.junit.Assert.assertEquals;
@@ -23,10 +25,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.hamcrest.MockitoHamcrest.argThat;
import android.accessibilityservice.MagnificationConfig;
import android.animation.ValueAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -105,6 +106,8 @@ public class FullScreenMagnificationControllerTest {
private final MagnificationScaleProvider mScaleProvider = mock(
MagnificationScaleProvider.class);
private final ArgumentCaptor<MagnificationConfig> mConfigCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
ValueAnimator mMockValueAnimator;
ValueAnimator.AnimatorUpdateListener mTargetAnimationListener;
@@ -142,13 +145,13 @@ public class FullScreenMagnificationControllerTest {
register(DISPLAY_1);
register(INVALID_DISPLAY);
verify(mMockContext).registerReceiver(
(BroadcastReceiver) anyObject(), (IntentFilter) anyObject());
any(BroadcastReceiver.class), any(IntentFilter.class));
verify(mMockWindowManager).setMagnificationCallbacks(
eq(DISPLAY_0), (MagnificationCallbacks) anyObject());
eq(DISPLAY_0), any(MagnificationCallbacks.class));
verify(mMockWindowManager).setMagnificationCallbacks(
eq(DISPLAY_1), (MagnificationCallbacks) anyObject());
eq(DISPLAY_1), any(MagnificationCallbacks.class));
verify(mMockWindowManager).setMagnificationCallbacks(
eq(INVALID_DISPLAY), (MagnificationCallbacks) anyObject());
eq(INVALID_DISPLAY), any(MagnificationCallbacks.class));
assertTrue(mFullScreenMagnificationController.isRegistered(DISPLAY_0));
assertTrue(mFullScreenMagnificationController.isRegistered(DISPLAY_1));
assertFalse(mFullScreenMagnificationController.isRegistered(INVALID_DISPLAY));
@@ -159,9 +162,9 @@ public class FullScreenMagnificationControllerTest {
register(DISPLAY_0);
register(DISPLAY_1);
mFullScreenMagnificationController.unregister(DISPLAY_0);
verify(mMockContext, times(0)).unregisterReceiver((BroadcastReceiver) anyObject());
verify(mMockContext, times(0)).unregisterReceiver(any(BroadcastReceiver.class));
mFullScreenMagnificationController.unregister(DISPLAY_1);
verify(mMockContext).unregisterReceiver((BroadcastReceiver) anyObject());
verify(mMockContext).unregisterReceiver(any(BroadcastReceiver.class));
verify(mMockWindowManager).setMagnificationCallbacks(eq(DISPLAY_0), eq(null));
verify(mMockWindowManager).setMagnificationCallbacks(eq(DISPLAY_1), eq(null));
assertFalse(mFullScreenMagnificationController.isRegistered(DISPLAY_0));
@@ -343,6 +346,7 @@ public class FullScreenMagnificationControllerTest {
MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
float scale = 2.5f;
PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
final MagnificationConfig config = buildConfig(scale, newCenter.x, newCenter.y);
PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
MagnificationSpec endSpec = getMagnificationSpec(scale, offsets);
@@ -353,8 +357,9 @@ public class FullScreenMagnificationControllerTest {
assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.5);
assertThat(getCurrentMagnificationSpec(displayId), closeTo(endSpec));
verify(mMockAms).notifyMagnificationChanged(displayId,
INITIAL_MAGNIFICATION_REGION, scale, newCenter.x, newCenter.y);
verify(mMockAms).notifyMagnificationChanged(eq(displayId), eq(INITIAL_MAGNIFICATION_REGION),
mConfigCaptor.capture());
assertConfigEquals(config, mConfigCaptor.getValue());
verify(mMockValueAnimator).start();
verify(mRequestObserver).onRequestMagnificationSpec(displayId, SERVICE_ID_1);
@@ -494,8 +499,11 @@ public class FullScreenMagnificationControllerTest {
MagnificationCallbacks callbacks = getMagnificationCallbacks(displayId);
callbacks.onMagnificationRegionChanged(OTHER_REGION);
mMessageCapturingHandler.sendAllMessages();
verify(mMockAms).notifyMagnificationChanged(displayId, OTHER_REGION, 1.0f,
OTHER_MAGNIFICATION_BOUNDS.centerX(), OTHER_MAGNIFICATION_BOUNDS.centerY());
MagnificationConfig config = buildConfig(1.0f, OTHER_MAGNIFICATION_BOUNDS.centerX(),
OTHER_MAGNIFICATION_BOUNDS.centerY());
verify(mMockAms).notifyMagnificationChanged(eq(displayId), eq(OTHER_REGION),
mConfigCaptor.capture());
assertConfigEquals(config, mConfigCaptor.getValue());
}
@Test
@@ -650,7 +658,7 @@ public class FullScreenMagnificationControllerTest {
reset(mMockAms);
assertTrue(mFullScreenMagnificationController.resetIfNeeded(displayId, false));
verify(mMockAms).notifyMagnificationChanged(eq(displayId),
eq(INITIAL_MAGNIFICATION_REGION), eq(1.0f), anyFloat(), anyFloat());
eq(INITIAL_MAGNIFICATION_REGION), any(MagnificationConfig.class));
assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
assertFalse(mFullScreenMagnificationController.resetIfNeeded(displayId, false));
}
@@ -668,8 +676,8 @@ public class FullScreenMagnificationControllerTest {
assertFalse(mFullScreenMagnificationController.reset(displayId, mAnimationCallback));
mMessageCapturingHandler.sendAllMessages();
verify(mMockAms, never()).notifyMagnificationChanged(eq(displayId),
any(Region.class), anyFloat(), anyFloat(), anyFloat());
verify(mMockAms, never()).notifyMagnificationChanged(eq(displayId), any(Region.class),
any(MagnificationConfig.class));
verify(mAnimationCallback).onResult(true);
}
@@ -726,7 +734,7 @@ public class FullScreenMagnificationControllerTest {
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
verify(mMockContext).registerReceiver(
broadcastReceiverCaptor.capture(), (IntentFilter) anyObject());
broadcastReceiverCaptor.capture(), any(IntentFilter.class));
BroadcastReceiver br = broadcastReceiverCaptor.getValue();
zoomIn2xToMiddle(DISPLAY_0);
zoomIn2xToMiddle(DISPLAY_1);
@@ -1031,6 +1039,7 @@ public class FullScreenMagnificationControllerTest {
MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
float scale = 2.5f;
PointF firstCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
final MagnificationConfig config = buildConfig(scale, firstCenter.x, firstCenter.y);
MagnificationSpec firstEndSpec = getMagnificationSpec(
scale, computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, firstCenter, scale));
@@ -1047,8 +1056,9 @@ public class FullScreenMagnificationControllerTest {
when(mMockValueAnimator.getAnimatedFraction()).thenReturn(0.0f);
mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
verify(mMockWindowManager).setMagnificationSpec(eq(displayId), eq(startSpec));
verify(mMockAms).notifyMagnificationChanged(displayId,
INITIAL_MAGNIFICATION_REGION, scale, firstCenter.x, firstCenter.y);
verify(mMockAms).notifyMagnificationChanged(eq(displayId), eq(INITIAL_MAGNIFICATION_REGION),
mConfigCaptor.capture());
assertConfigEquals(config, mConfigCaptor.getValue());
Mockito.reset(mMockWindowManager);
// Intermediate point
@@ -1062,6 +1072,7 @@ public class FullScreenMagnificationControllerTest {
Mockito.reset(mMockWindowManager);
PointF newCenter = INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER;
final MagnificationConfig newConfig = buildConfig(scale, newCenter.x, newCenter.y);
MagnificationSpec newEndSpec = getMagnificationSpec(
scale, computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale));
assertTrue(mFullScreenMagnificationController.setCenter(displayId,
@@ -1070,8 +1081,9 @@ public class FullScreenMagnificationControllerTest {
// Animation should have been restarted
verify(mMockValueAnimator, times(2)).start();
verify(mMockAms).notifyMagnificationChanged(displayId,
INITIAL_MAGNIFICATION_REGION, scale, newCenter.x, newCenter.y);
verify(mMockAms, times(2)).notifyMagnificationChanged(eq(displayId),
eq(INITIAL_MAGNIFICATION_REGION), mConfigCaptor.capture());
assertConfigEquals(newConfig, mConfigCaptor.getValue());
// New starting point should be where we left off
when(mMockValueAnimator.getAnimatedFraction()).thenReturn(0.0f);
@@ -1155,7 +1167,7 @@ public class FullScreenMagnificationControllerTest {
Region regionArg = (Region) args[1];
regionArg.set(INITIAL_MAGNIFICATION_REGION);
return null;
}).when(mMockWindowManager).getMagnificationRegion(anyInt(), (Region) anyObject());
}).when(mMockWindowManager).getMagnificationRegion(anyInt(), any(Region.class));
}
private void resetMockWindowManager() {
@@ -1201,6 +1213,19 @@ public class FullScreenMagnificationControllerTest {
magnifiedBounds.centerY() - scale * center.y);
}
private MagnificationConfig buildConfig(float scale, float centerX, float centerY) {
return new MagnificationConfig.Builder().setMode(
MAGNIFICATION_MODE_FULLSCREEN).setScale(scale).setCenterX(centerX).setCenterY(
centerY).build();
}
private void assertConfigEquals(MagnificationConfig expected, MagnificationConfig result) {
assertEquals(expected.getMode(), result.getMode());
assertEquals(expected.getScale(), result.getScale(), 0f);
assertEquals(expected.getCenterX(), result.getCenterX(), 0f);
assertEquals(expected.getCenterY(), result.getCenterY(), 0f);
}
private MagnificationSpec getInterpolatedMagSpec(MagnificationSpec start, MagnificationSpec end,
float fraction) {
MagnificationSpec interpolatedSpec = new MagnificationSpec();

View File

@@ -429,6 +429,21 @@ public class MagnificationControllerTest {
verify(mWindowMagnificationManager).persistScale(eq(TEST_DISPLAY));
}
@Test
public void onSourceBoundsChanged_notifyMagnificationChanged() {
Rect rect = new Rect(0, 0, 100, 120);
Region region = new Region(rect);
mMagnificationController.onSourceBoundsChanged(TEST_DISPLAY, rect);
final ArgumentCaptor<MagnificationConfig> configCaptor = ArgumentCaptor.forClass(
MagnificationConfig.class);
verify(mService).notifyMagnificationChanged(eq(TEST_DISPLAY), eq(region),
configCaptor.capture());
assertEquals(rect.exactCenterX(), configCaptor.getValue().getCenterX(), 0);
assertEquals(rect.exactCenterY(), configCaptor.getValue().getCenterY(), 0);
}
@Test
public void onAccessibilityActionPerformed_magnifierEnabled_showMagnificationButton()
throws RemoteException {