Merge changes from topics "presubmit-am-8e1f6f3832184ab4980013d926d31388", "presubmit-am-a0b2814b27254513b7a62e0a1e0044ff" into tm-dev

* changes:
  Enables following typing functionality when the window magnifier is on again.
  Adds moveWindowMagnifierToPosition method
This commit is contained in:
Daniel Hsieh
2022-03-02 01:21:14 +00:00
committed by Android (Google) Code Review
13 changed files with 477 additions and 47 deletions

View File

@@ -32,7 +32,7 @@ oneway interface IWindowMagnificationConnection {
/**
* Enables window magnification on specified display with given center and scale and animation.
*
* @param displayId The logical display id.
* @param displayId the logical display id.
* @param scale magnification scale.
* @param centerX the screen-relative X coordinate around which to center,
* or {@link Float#NaN} to leave unchanged.
@@ -51,7 +51,7 @@ oneway interface IWindowMagnificationConnection {
/**
* Sets the scale of the window magnifier on specified display.
*
* @param displayId The logical display id.
* @param displayId the logical display id.
* @param scale magnification scale.
*/
void setScale(int displayId, float scale);
@@ -59,7 +59,7 @@ oneway interface IWindowMagnificationConnection {
/**
* Disables window magnification on specified display with animation.
*
* @param displayId The logical display id.
* @param displayId the logical display id.
* @param callback The callback called when the animation is completed or interrupted.
*/
void disableWindowMagnification(int displayId,
@@ -68,6 +68,7 @@ oneway interface IWindowMagnificationConnection {
/**
* Moves the window magnifier on the specified display. It has no effect while animating.
*
* @param displayId the logical display id.
* @param offsetX the amount in pixels to offset the window magnifier in the X direction, in
* current screen pixels.
* @param offsetY the amount in pixels to offset the window magnifier in the Y direction, in
@@ -75,10 +76,21 @@ oneway interface IWindowMagnificationConnection {
*/
void moveWindowMagnifier(int displayId, float offsetX, float offsetY);
/**
* Moves the window magnifier on the given display.
*
* @param displayId the logical display id.
* @param positionX the x-axis position of the center of the magnified source bounds.
* @param positionY the y-axis position of the center of the magnified source bounds.
* @param callback the callback called when the animation is completed or interrupted.
*/
void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
in IRemoteMagnificationAnimationCallback callback);
/**
* Requests System UI show magnification mode button UI on the specified display.
*
* @param displayId The logical display id.
* @param displayId the logical display id.
* @param magnificationMode the current magnification mode.
*/
void showMagnificationButton(int displayId, int magnificationMode);
@@ -86,7 +98,7 @@ oneway interface IWindowMagnificationConnection {
/**
* Requests System UI remove magnification mode button UI on the specified display.
*
* @param displayId The logical display id.
* @param displayId the logical display id.
*/
void removeMagnificationButton(int displayId);

View File

@@ -171,6 +171,17 @@ public class WindowMagnification extends CoreStartable implements WindowMagnifie
}
}
@MainThread
void moveWindowMagnifierToPositionInternal(int displayId, float positionX, float positionY,
IRemoteMagnificationAnimationCallback callback) {
final WindowMagnificationController windowMagnificationController =
mMagnificationControllerSupplier.get(displayId);
if (windowMagnificationController != null) {
windowMagnificationController.moveWindowMagnifierToPosition(positionX, positionY,
callback);
}
}
@MainThread
void disableWindowMagnification(int displayId,
@Nullable IRemoteMagnificationAnimationCallback callback) {

View File

@@ -156,6 +156,7 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
}
mAnimationCallback = animationCallback;
setupEnableAnimationSpecs(scale, centerX, centerY);
if (mEndSpec.equals(mStartSpec)) {
if (mState == STATE_DISABLED) {
mController.enableWindowMagnificationInternal(scale, centerX, centerY,
@@ -178,6 +179,24 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
}
}
void moveWindowMagnifierToPosition(float centerX, float centerY,
IRemoteMagnificationAnimationCallback callback) {
if (mState == STATE_ENABLED) {
// We set the animation duration to shortAnimTime which would be reset at the end.
mValueAnimator.setDuration(mContext.getResources()
.getInteger(com.android.internal.R.integer.config_shortAnimTime));
enableWindowMagnification(Float.NaN, centerX, centerY,
/* magnificationFrameOffsetRatioX */ Float.NaN,
/* magnificationFrameOffsetRatioY */ Float.NaN, callback);
} else if (mState == STATE_ENABLING) {
sendAnimationCallback(false);
mAnimationCallback = callback;
mValueAnimator.setDuration(mContext.getResources()
.getInteger(com.android.internal.R.integer.config_shortAnimTime));
setupEnableAnimationSpecs(Float.NaN, centerX, centerY);
}
}
private void setupEnableAnimationSpecs(float scale, float centerX, float centerY) {
if (mController == null) {
return;
@@ -193,9 +212,16 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
R.integer.magnification_default_scale) : scale, centerX, centerY);
} else {
mStartSpec.set(currentScale, currentCenterX, currentCenterY);
mEndSpec.set(Float.isNaN(scale) ? currentScale : scale,
Float.isNaN(centerX) ? currentCenterX : centerX,
Float.isNaN(centerY) ? currentCenterY : centerY);
final float endScale = (mState == STATE_ENABLING ? mEndSpec.mScale : currentScale);
final float endCenterX =
(mState == STATE_ENABLING ? mEndSpec.mCenterX : currentCenterX);
final float endCenterY =
(mState == STATE_ENABLING ? mEndSpec.mCenterY : currentCenterY);
mEndSpec.set(Float.isNaN(scale) ? endScale : scale,
Float.isNaN(centerX) ? endCenterX : centerX,
Float.isNaN(centerY) ? endCenterY : centerY);
}
if (DEBUG) {
Log.d(TAG, "SetupEnableAnimationSpecs : mStartSpec = " + mStartSpec + ", endSpec = "
@@ -269,6 +295,9 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
setState(STATE_ENABLED);
}
sendAnimationCallback(true);
// We reset the duration to config_longAnimTime
mValueAnimator.setDuration(mContext.getResources()
.getInteger(com.android.internal.R.integer.config_longAnimTime));
}
@Override
@@ -313,10 +342,10 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
}
private static ValueAnimator newValueAnimator(Resources resources) {
private static ValueAnimator newValueAnimator(Resources resource) {
final ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(
resources.getInteger(com.android.internal.R.integer.config_longAnimTime));
resource.getInteger(com.android.internal.R.integer.config_longAnimTime));
valueAnimator.setInterpolator(new AccelerateInterpolator(2.5f));
valueAnimator.setFloatValues(0.0f, 1.0f);
return valueAnimator;

View File

@@ -76,6 +76,13 @@ class WindowMagnificationConnectionImpl extends IWindowMagnificationConnection.S
() -> mWindowMagnification.moveWindowMagnifier(displayId, offsetX, offsetY));
}
@Override
public void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
IRemoteMagnificationAnimationCallback callback) {
mHandler.post(() -> mWindowMagnification.moveWindowMagnifierToPositionInternal(
displayId, positionX, positionY, callback));
}
@Override
public void showMagnificationButton(int displayId, int magnificationMode) {
mHandler.post(

View File

@@ -985,6 +985,14 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
}
}
void moveWindowMagnifierToPosition(float positionX, float positionY,
IRemoteMagnificationAnimationCallback callback) {
if (mMirrorSurfaceView == null) {
return;
}
mAnimationController.moveWindowMagnifierToPosition(positionX, positionY, callback);
}
/**
* Gets the scale.
*

View File

@@ -133,6 +133,16 @@ public class IWindowMagnificationConnectionTest extends SysuiTestCase {
verify(mWindowMagnificationController).moveWindowMagnifier(100f, 200f);
}
@Test
public void moveWindowMagnifierToPosition() throws RemoteException {
mIWindowMagnificationConnection.moveWindowMagnifierToPosition(TEST_DISPLAY,
100f, 200f, mAnimationCallback);
waitForIdleSync();
verify(mWindowMagnificationController).moveWindowMagnifierToPosition(
eq(100f), eq(200f), any(IRemoteMagnificationAnimationCallback.class));
}
@Test
public void showMagnificationButton() throws RemoteException {
mIWindowMagnificationConnection.showMagnificationButton(TEST_DISPLAY,

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.accessibility;
import android.os.RemoteException;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class MockMagnificationAnimationCallback extends IRemoteMagnificationAnimationCallback.Stub {
private final CountDownLatch mCountDownLatch;
private final AtomicInteger mSuccessCount;
private final AtomicInteger mFailedCount;
MockMagnificationAnimationCallback(CountDownLatch countDownLatch) {
mCountDownLatch = countDownLatch;
mSuccessCount = new AtomicInteger();
mFailedCount = new AtomicInteger();
}
public int getSuccessCount() {
return mSuccessCount.get();
}
public int getFailedCount() {
return mFailedCount.get();
}
@Override
public void onResult(boolean success) throws RemoteException {
mCountDownLatch.countDown();
if (success) {
mSuccessCount.getAndIncrement();
} else {
mFailedCount.getAndIncrement();
}
}
}

View File

@@ -60,6 +60,8 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@Ignore
@@ -217,6 +219,29 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
verify(mAnimationCallback2).onResult(true);
}
@Test
public void enableWindowMagnificationWithUnchanged_enabling_expectedValuesToDefault()
throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(2);
final MockMagnificationAnimationCallback animationCallback =
new MockMagnificationAnimationCallback(countDownLatch);
enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
animationCallback);
mInstrumentation.runOnMainSync(
() -> {
mWindowMagnificationAnimationController.enableWindowMagnification(Float.NaN,
Float.NaN, Float.NaN, animationCallback);
});
assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
// The callback in 2nd enableWindowMagnification will return true
assertEquals(1, animationCallback.getSuccessCount());
// The callback in 1st enableWindowMagnification will return false
assertEquals(1, animationCallback.getFailedCount());
verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X, DEFAULT_CENTER_Y);
}
@Test
public void enableWindowMagnificationWithScaleOne_enabled_AnimationAndInvokeCallback()
throws RemoteException {
@@ -424,6 +449,102 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
Math.round(offsetRatio * mirrorViewBound.height() / 2), 0.1f);
}
@Test
public void moveWindowMagnifierToPosition_enabled_expectedValues()
throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final MockMagnificationAnimationCallback animationCallback =
new MockMagnificationAnimationCallback(countDownLatch);
final float targetCenterX = DEFAULT_CENTER_X + 100;
final float targetCenterY = DEFAULT_CENTER_Y + 100;
enableWindowMagnificationWithoutAnimation();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
targetCenterX, targetCenterY, animationCallback);
});
assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
assertEquals(1, animationCallback.getSuccessCount());
assertEquals(0, animationCallback.getFailedCount());
verifyFinalSpec(DEFAULT_SCALE, targetCenterX, targetCenterY);
}
@Test
public void moveWindowMagnifierToPositionMultipleTimes_enabled_expectedValuesToLastOne()
throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(4);
final MockMagnificationAnimationCallback animationCallback =
new MockMagnificationAnimationCallback(countDownLatch);
enableWindowMagnificationWithoutAnimation();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
DEFAULT_CENTER_X + 10, DEFAULT_CENTER_Y + 10, animationCallback);
mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
DEFAULT_CENTER_X + 20, DEFAULT_CENTER_Y + 20, animationCallback);
mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
DEFAULT_CENTER_X + 30, DEFAULT_CENTER_Y + 30, animationCallback);
mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
DEFAULT_CENTER_X + 40, DEFAULT_CENTER_Y + 40, animationCallback);
});
assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
// only the last one callback will return true
assertEquals(1, animationCallback.getSuccessCount());
// the others will return false
assertEquals(3, animationCallback.getFailedCount());
verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X + 40, DEFAULT_CENTER_Y + 40);
}
@Test
public void moveWindowMagnifierToPosition_enabling_expectedValuesToLastOne()
throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(2);
final MockMagnificationAnimationCallback animationCallback =
new MockMagnificationAnimationCallback(countDownLatch);
final float targetCenterX = DEFAULT_CENTER_X + 100;
final float targetCenterY = DEFAULT_CENTER_Y + 100;
enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
animationCallback);
mInstrumentation.runOnMainSync(
() -> {
mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
targetCenterX, targetCenterY, animationCallback);
});
assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
// The callback in moveWindowMagnifierToPosition will return true
assertEquals(1, animationCallback.getSuccessCount());
// The callback in enableWindowMagnification will return false
assertEquals(1, animationCallback.getFailedCount());
verifyFinalSpec(DEFAULT_SCALE, targetCenterX, targetCenterY);
}
@Test
public void moveWindowMagnifierToPositionWithCenterUnchanged_enabling_expectedValuesToDefault()
throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(2);
final MockMagnificationAnimationCallback animationCallback =
new MockMagnificationAnimationCallback(countDownLatch);
enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
animationCallback);
mInstrumentation.runOnMainSync(
() -> {
mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
Float.NaN, Float.NaN, animationCallback);
});
assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
// The callback in moveWindowMagnifierToPosition will return true
assertEquals(1, animationCallback.getSuccessCount());
// The callback in enableWindowMagnification will return false
assertEquals(1, animationCallback.getFailedCount());
verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X, DEFAULT_CENTER_Y);
}
@Test
public void enableWindowMagnificationWithSameScale_enabled_doNothingButInvokeCallback()
throws RemoteException {
@@ -569,6 +690,20 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X + 100f, DEFAULT_CENTER_Y + 100f);
}
@Test
public void moveWindowMagnifierToPosition_enabled() {
final float targetCenterX = DEFAULT_CENTER_X + 100;
final float targetCenterY = DEFAULT_CENTER_Y + 100;
enableWindowMagnificationWithoutAnimation();
mInstrumentation.runOnMainSync(
() -> mController.moveWindowMagnifierToPosition(targetCenterX, targetCenterY,
mAnimationCallback));
SystemClock.sleep(mWaitingAnimationPeriod);
verifyFinalSpec(DEFAULT_SCALE, targetCenterX, targetCenterY);
}
private void verifyFinalSpec(float expectedScale, float expectedCenterX,
float expectedCenterY) {
assertEquals(expectedScale, mController.getScale(), 0f);
@@ -662,6 +797,13 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
mSpyController.moveWindowMagnifier(offsetX, offsetY);
}
@Override
void moveWindowMagnifierToPosition(float positionX, float positionY,
IRemoteMagnificationAnimationCallback callback) {
super.moveWindowMagnifierToPosition(positionX, positionY, callback);
mSpyController.moveWindowMagnifierToPosition(positionX, positionY, callback);
}
@Override
void setScale(float scale) {
super.setScale(scale);

View File

@@ -88,6 +88,8 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@LargeTest
@@ -96,12 +98,16 @@ import java.util.concurrent.atomic.AtomicInteger;
public class WindowMagnificationControllerTest extends SysuiTestCase {
private static final int LAYOUT_CHANGE_TIMEOUT_MS = 5000;
private static final long ANIMATION_DURATION_MS = 300;
private final long mWaitingAnimationPeriod = 2 * ANIMATION_DURATION_MS;
@Mock
private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
@Mock
private MirrorWindowControl mMirrorWindowControl;
@Mock
private WindowMagnifierCallback mWindowMagnifierCallback;
@Mock
IRemoteMagnificationAnimationCallback mAnimationCallback;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
@@ -286,6 +292,82 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
verify(mSfVsyncFrameProvider, atLeastOnce()).postFrameCallback(any());
}
@Test
public void moveWindowMagnifierToPositionWithAnimation_expectedValuesAndInvokeCallback()
throws InterruptedException {
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
Float.NaN, 0, 0, null);
});
final CountDownLatch countDownLatch = new CountDownLatch(1);
final MockMagnificationAnimationCallback animationCallback =
new MockMagnificationAnimationCallback(countDownLatch);
final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
.onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
final float targetCenterX = sourceBoundsCaptor.getValue().exactCenterX() + 10;
final float targetCenterY = sourceBoundsCaptor.getValue().exactCenterY() + 10;
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.moveWindowMagnifierToPosition(
targetCenterX, targetCenterY, animationCallback);
});
assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
assertEquals(1, animationCallback.getSuccessCount());
assertEquals(0, animationCallback.getFailedCount());
verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
.onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
assertEquals(mWindowMagnificationController.getCenterX(),
sourceBoundsCaptor.getValue().exactCenterX(), 0);
assertEquals(mWindowMagnificationController.getCenterY(),
sourceBoundsCaptor.getValue().exactCenterY(), 0);
assertEquals(mWindowMagnificationController.getCenterX(), targetCenterX, 0);
assertEquals(mWindowMagnificationController.getCenterY(), targetCenterY, 0);
}
@Test
public void moveWindowMagnifierToPositionMultipleTimes_expectedValuesAndInvokeCallback()
throws InterruptedException {
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
Float.NaN, 0, 0, null);
});
final CountDownLatch countDownLatch = new CountDownLatch(4);
final MockMagnificationAnimationCallback animationCallback =
new MockMagnificationAnimationCallback(countDownLatch);
final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
.onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
final float centerX = sourceBoundsCaptor.getValue().exactCenterX();
final float centerY = sourceBoundsCaptor.getValue().exactCenterY();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.moveWindowMagnifierToPosition(
centerX + 10, centerY + 10, animationCallback);
mWindowMagnificationController.moveWindowMagnifierToPosition(
centerX + 20, centerY + 20, animationCallback);
mWindowMagnificationController.moveWindowMagnifierToPosition(
centerX + 30, centerY + 30, animationCallback);
mWindowMagnificationController.moveWindowMagnifierToPosition(
centerX + 40, centerY + 40, animationCallback);
});
assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
// only the last one callback will return true
assertEquals(1, animationCallback.getSuccessCount());
// the others will return false
assertEquals(3, animationCallback.getFailedCount());
verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
.onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
assertEquals(mWindowMagnificationController.getCenterX(),
sourceBoundsCaptor.getValue().exactCenterX(), 0);
assertEquals(mWindowMagnificationController.getCenterY(),
sourceBoundsCaptor.getValue().exactCenterY(), 0);
assertEquals(mWindowMagnificationController.getCenterX(), centerX + 40, 0);
assertEquals(mWindowMagnificationController.getCenterY(), centerY + 40, 0);
}
@Test
public void setScale_enabled_expectedValueAndUpdateStateDescription() {
mInstrumentation.runOnMainSync(

View File

@@ -133,6 +133,25 @@ class WindowMagnificationConnectionWrapper {
return true;
}
boolean moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
@Nullable MagnificationAnimationCallback callback) {
if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
mTrace.logTrace(TAG + ".moveWindowMagnifierToPosition",
FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "displayId=" + displayId
+ ";positionX=" + positionX + ";positionY=" + positionY);
}
try {
mConnection.moveWindowMagnifierToPosition(displayId, positionX, positionY,
transformToRemoteCallback(callback, mTrace));
} catch (RemoteException e) {
if (DBG) {
Slog.e(TAG, "Error calling moveWindowMagnifierToPosition()", e);
}
return false;
}
return true;
}
boolean showMagnificationButton(int displayId, int magnificationMode) {
if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
mTrace.logTrace(TAG + ".showMagnificationButton",

View File

@@ -383,9 +383,12 @@ public class WindowMagnificationManager implements
float toCenterX = (float) (left + right) / 2;
float toCenterY = (float) (top + bottom) / 2;
if (!isPositionInSourceBounds(displayId, toCenterX, toCenterY)
&& isTrackingTypingFocusEnabled(displayId)) {
enableWindowMagnification(displayId, Float.NaN, toCenterX, toCenterY);
synchronized (mLock) {
if (!isPositionInSourceBounds(displayId, toCenterX, toCenterY)
&& isTrackingTypingFocusEnabled(displayId)) {
moveWindowMagnifierToPositionInternal(displayId, toCenterX, toCenterY,
STUB_ANIMATION_CALLBACK);
}
}
}
@@ -426,7 +429,7 @@ public class WindowMagnificationManager implements
* @param displayId The logical display id.
* @param trackingTypingFocusEnabled Enabled or disable the function of tracking typing focus.
*/
private void setTrackingTypingFocusEnabled(int displayId, boolean trackingTypingFocusEnabled) {
void setTrackingTypingFocusEnabled(int displayId, boolean trackingTypingFocusEnabled) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
@@ -569,8 +572,11 @@ public class WindowMagnificationManager implements
animationCallback, windowPosition, id);
}
if (enabled && !previousEnabled) {
mCallback.onWindowMagnificationActivationState(displayId, true);
if (enabled) {
setTrackingTypingFocusEnabled(displayId, true);
if (!previousEnabled) {
mCallback.onWindowMagnificationActivationState(displayId, true);
}
}
return enabled;
}
@@ -632,14 +638,13 @@ public class WindowMagnificationManager implements
}
}
@GuardedBy("mLock")
boolean isPositionInSourceBounds(int displayId, float x, float y) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
return false;
}
return magnifier.isPositionInSourceBounds(x, y);
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
return false;
}
return magnifier.isPositionInSourceBounds(x, y);
}
/**
@@ -954,7 +959,6 @@ public class WindowMagnificationManager implements
mWindowMagnificationManager = windowMagnificationManager;
}
@GuardedBy("mLock")
boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY,
@Nullable MagnificationAnimationCallback animationCallback,
@WindowPosition int windowPosition, int id) {
@@ -1032,7 +1036,6 @@ public class WindowMagnificationManager implements
return mIdOfLastServiceToControl;
}
@GuardedBy("mLock")
int pointersInWindow(MotionEvent motionEvent) {
int count = 0;
final int pointerCount = motionEvent.getPointerCount();
@@ -1131,8 +1134,16 @@ public class WindowMagnificationManager implements
displayId, animationCallback);
}
@GuardedBy("mLock")
private boolean moveWindowMagnifierInternal(int displayId, float offsetX, float offsetY) {
return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifier(
displayId, offsetX, offsetY);
}
@GuardedBy("mLock")
private boolean moveWindowMagnifierToPositionInternal(int displayId, float positionX,
float positionY, MagnificationAnimationCallback animationCallback) {
return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifierToPosition(
displayId, positionX, positionY, animationCallback);
}
}

View File

@@ -93,6 +93,14 @@ public class WindowMagnificationConnectionWrapperTest {
verify(mConnection).moveWindowMagnifier(TEST_DISPLAY, 100, 150);
}
@Test
public void moveWindowMagnifierToPosition() throws RemoteException {
mConnectionWrapper.moveWindowMagnifierToPosition(TEST_DISPLAY, 100, 150,
mAnimationCallback);
verify(mConnection).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
eq(100f), eq(150f), any(IRemoteMagnificationAnimationCallback.class));
}
@Test
public void showMagnificationButton() throws RemoteException {
mConnectionWrapper.showMagnificationButton(TEST_DISPLAY,

View File

@@ -21,6 +21,8 @@ import static com.android.server.accessibility.magnification.MockWindowMagnifica
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.doAnswer;
@@ -291,7 +293,7 @@ public class WindowMagnificationManagerTest {
}
@Test
public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnification()
public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier()
throws RemoteException {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
@@ -304,14 +306,13 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never()).enableWindowMagnification(eq(TEST_DISPLAY),
eq(3f), eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
eq(0f), eq(0f), notNull());
verify(mMockConnection.getConnection(), never())
.moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
}
@Test
public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnification()
public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnifier()
throws RemoteException {
final float distanceX = 10f;
final float distanceY = 10f;
@@ -326,13 +327,12 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never()).enableWindowMagnification(eq(TEST_DISPLAY),
eq(3f), eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
eq(0f), eq(0f), notNull());
verify(mMockConnection.getConnection(), never())
.moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
}
@Test
public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnification()
public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnifier()
throws RemoteException {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
@@ -344,12 +344,12 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection(), never()).enableWindowMagnification(eq(TEST_DISPLAY),
eq(3f), eq(500f), eq(500f), eq(0f), eq(0f), notNull());
verify(mMockConnection.getConnection(), never())
.moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
}
@Test
public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnification()
public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier()
throws RemoteException {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
@@ -361,18 +361,16 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
eq(0f), eq(0f), notNull());
any(IRemoteMagnificationAnimationCallback.class));
}
@Test
public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnification()
public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier()
throws RemoteException {
final PointF initialPoint = new PointF(50f, 50f);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f,
initialPoint.x, initialPoint.y);
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
mMockConnection.getConnectionCallback().onDrag(TEST_DISPLAY);
mWindowMagnificationManager.onImeWindowVisibilityChanged(true);
final Region outRegion = new Region();
@@ -383,14 +381,13 @@ public class WindowMagnificationManagerTest {
mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY),
eq(3f), eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
eq(0f), eq(0f), notNull());
verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
any(IRemoteMagnificationAnimationCallback.class));
}
@Test
public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnification()
throws RemoteException {
public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
final Region beforeRegion = new Region();
@@ -407,6 +404,46 @@ public class WindowMagnificationManagerTest {
assertEquals(afterRegion, beforeRegion);
}
@Test
public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
final Region beforeRegion = new Region();
mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
final Rect requestedRect = beforeRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
final Region afterRegion = new Region();
mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
assertEquals(afterRegion, beforeRegion);
}
@Test
public void onRectangleOnScreenRequested_trackingDisabledAndEnabledMagnifier_movingMagnifier()
throws RemoteException {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
final Region beforeRegion = new Region();
mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
final Rect requestedRect = beforeRegion.getBounds();
requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
// Enabling a window magnifier again will turn on the tracking typing focus functionality.
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN);
mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
any(IRemoteMagnificationAnimationCallback.class));
}
@Test
public void moveWindowMagnifier_enabled_invokeConnectionMethod() throws RemoteException {
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());