Change magnification animation callback (2/2)
We send callback when the animation is canceled/reversed due to
the new quest while animating.
Bug: 161669184
Test: atest com.android.systemui.accessibility
atest com.android.server.accessibility.magnification
Change-Id: Iecd5e1bcf0ac097d4271ff0d277872b1dab0c63d
diff --git a/core/java/android/view/accessibility/IRemoteMagnificationAnimationCallback.aidl b/core/java/android/view/accessibility/IRemoteMagnificationAnimationCallback.aidl
new file mode 100644
index 0000000..946ea16
--- /dev/null
+++ b/core/java/android/view/accessibility/IRemoteMagnificationAnimationCallback.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2019 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 android.view.accessibility;
+
+/**
+ * A callback for magnification animation result.
+ * @hide
+ */
+
+ oneway interface IRemoteMagnificationAnimationCallback {
+
+ /**
+ * Called when the animation is finished or interrupted during animating.
+ *
+ * @param success {@code true} if animating successfully with given spec or the spec did not
+ * change. Otherwise {@code false}
+ */
+ void onResult(boolean success);
+}
diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
index ae853e9..ddf68fc 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
@@ -18,8 +18,8 @@
import android.graphics.PointF;
import android.graphics.Rect;
-import android.os.RemoteCallback;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
/**
* Interface for interaction between {@link AccessibilityManagerService}
@@ -38,10 +38,10 @@
* or {@link Float#NaN} to leave unchanged.
* @param centerY the screen-relative Y coordinate around which to center,
* or {@link Float#NaN} to leave unchanged.
- * @param endCallback The callback called when the animation is completed.
+ * @param callback The callback called when the animation is completed or interrupted.
*/
void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
- in RemoteCallback endCallback);
+ in IRemoteMagnificationAnimationCallback callback);
/**
* Sets the scale of the window magnifier on specified display.
@@ -55,9 +55,10 @@
* Disables window magnification on specified display with animation.
*
* @param displayId The logical display id.
- * @param endCallback The callback called when the animation is completed.
+ * @param callback The callback called when the animation is completed or interrupted.
*/
- void disableWindowMagnification(int displayId, in RemoteCallback endCallback);
+ void disableWindowMagnification(int displayId,
+ in IRemoteMagnificationAnimationCallback callback);
/**
* Moves the window magnifier on the specified display. It has no effect while animating.
diff --git a/core/java/android/view/accessibility/MagnificationAnimationCallback.java b/core/java/android/view/accessibility/MagnificationAnimationCallback.java
index 491f7fb..bc9fb0a 100644
--- a/core/java/android/view/accessibility/MagnificationAnimationCallback.java
+++ b/core/java/android/view/accessibility/MagnificationAnimationCallback.java
@@ -28,4 +28,4 @@
* change. Otherwise {@code false}
*/
void onResult(boolean success);
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index e10d2be..911bf9e 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -24,11 +24,11 @@
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
-import android.os.RemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import android.view.SurfaceControl;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
@@ -101,10 +101,10 @@
@MainThread
void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
- @Nullable RemoteCallback endCallback) {
+ @Nullable IRemoteMagnificationAnimationCallback callback) {
//TODO: b/144080869 support multi-display.
mWindowMagnificationAnimationController.enableWindowMagnification(scale, centerX, centerY,
- endCallback != null ? () -> endCallback.sendResult(null) : null);
+ callback);
}
@MainThread
@@ -120,10 +120,10 @@
}
@MainThread
- void disableWindowMagnification(int displayId, @Nullable RemoteCallback endCallback) {
+ void disableWindowMagnification(int displayId,
+ @Nullable IRemoteMagnificationAnimationCallback callback) {
//TODO: b/144080869 support multi-display.
- mWindowMagnificationAnimationController.deleteWindowMagnification(
- endCallback != null ? () -> endCallback.sendResult(null) : null);
+ mWindowMagnificationAnimationController.deleteWindowMagnification(callback);
}
@Override
@@ -182,10 +182,10 @@
@Override
public void enableWindowMagnification(int displayId, float scale, float centerX,
- float centerY, RemoteCallback remoteCallback) {
+ float centerY, IRemoteMagnificationAnimationCallback callback) {
mHandler.post(
() -> mWindowMagnification.enableWindowMagnification(displayId, scale, centerX,
- centerY, remoteCallback));
+ centerY, callback));
}
@Override
@@ -194,9 +194,10 @@
}
@Override
- public void disableWindowMagnification(int displayId, RemoteCallback remoteCallback) {
+ public void disableWindowMagnification(int displayId,
+ IRemoteMagnificationAnimationCallback callback) {
mHandler.post(() -> mWindowMagnification.disableWindowMagnification(displayId,
- remoteCallback));
+ callback));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
index 2f2e3ea..24d8388 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
@@ -22,7 +22,9 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
+import android.os.RemoteException;
import android.util.Log;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.animation.AccelerateInterpolator;
import com.android.internal.annotations.VisibleForTesting;
@@ -38,7 +40,7 @@
class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUpdateListener,
Animator.AnimatorListener {
- private static final String TAG = "WindowMagnificationBridge";
+ private static final String TAG = "WindowMagnificationAnimationController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@Retention(RetentionPolicy.SOURCE)
@@ -61,7 +63,7 @@
private final Context mContext;
// Called when the animation is ended successfully without cancelling or mStartSpec and
// mEndSpec are equal.
- private Runnable mAnimationEndCallback;
+ private IRemoteMagnificationAnimationCallback mAnimationCallback;
// The flag to ignore the animation end callback.
private boolean mEndAnimationCanceled = false;
@MagnificationState
@@ -93,14 +95,16 @@
* or {@link Float#NaN} to leave unchanged.
* @param centerY The screen-relative Y coordinate around which to center,
* or {@link Float#NaN} to leave unchanged.
- * @param animationEndCallback Called when the transition is complete or the given arguments
- * are as same as current values.
+ * @param animationCallback Called when the transition is complete, the given arguments
+ * are as same as current values, or the transition is interrupted
+ * due to the new transition request.
*
* @see #onAnimationUpdate(ValueAnimator)
*/
void enableWindowMagnification(float scale, float centerX, float centerY,
- @Nullable Runnable animationEndCallback) {
- mAnimationEndCallback = animationEndCallback;
+ @Nullable IRemoteMagnificationAnimationCallback animationCallback) {
+ sendAnimationCallback(false);
+ mAnimationCallback = animationCallback;
setupEnableAnimationSpecs(scale, centerX, centerY);
if (mEndSpec.equals(mStartSpec)) {
if (mState == STATE_DISABLED) {
@@ -108,7 +112,7 @@
} else if (mState == STATE_ENABLING || mState == STATE_DISABLING) {
mValueAnimator.cancel();
}
- sendCallbackIfNeeded();
+ sendAnimationCallback(true);
setState(STATE_ENABLED);
} else {
if (mState == STATE_DISABLING) {
@@ -160,14 +164,17 @@
* Wraps {@link WindowMagnificationController#deleteWindowMagnification()}} with transition
* animation. If the window magnification is enabling, it runs the animation in reverse.
*
- * @param animationEndCallback Called when the transition is complete or the window
- * magnification is disabled already.
+ * @param animationCallback Called when the transition is complete, the given arguments
+ * are as same as current values, or the transition is interrupted
+ * due to the new transition request.
*/
- void deleteWindowMagnification(@Nullable Runnable animationEndCallback) {
- mAnimationEndCallback = animationEndCallback;
+ void deleteWindowMagnification(
+ @Nullable IRemoteMagnificationAnimationCallback animationCallback) {
+ sendAnimationCallback(false);
+ mAnimationCallback = animationCallback;
if (mState == STATE_DISABLED || mState == STATE_DISABLING) {
if (mState == STATE_DISABLED) {
- sendCallbackIfNeeded();
+ sendAnimationCallback(true);
}
return;
}
@@ -220,7 +227,7 @@
} else {
setState(STATE_ENABLED);
}
- sendCallbackIfNeeded();
+ sendAnimationCallback(true);
}
@Override
@@ -236,10 +243,17 @@
public void onAnimationRepeat(Animator animation) {
}
- private void sendCallbackIfNeeded() {
- if (mAnimationEndCallback != null) {
- mAnimationEndCallback.run();
- mAnimationEndCallback = null;
+ private void sendAnimationCallback(boolean success) {
+ if (mAnimationCallback != null) {
+ try {
+ mAnimationCallback.onResult(success);
+ if (DEBUG) {
+ Log.d(TAG, "sendAnimationCallback success = " + success);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "sendAnimationCallback failed : " + e);
+ }
+ mAnimationCallback = null;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index 9079338..1e969c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -23,13 +23,13 @@
import static org.mockito.Mockito.verify;
import android.content.Context;
-import android.os.RemoteCallback;
import android.os.RemoteException;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
@@ -41,7 +41,6 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -66,8 +65,7 @@
@Mock
private ModeSwitchesController mModeSwitchesController;
@Mock
- private RemoteCallback mRemoteCallback;
- private ArgumentCaptor<Runnable> mRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ private IRemoteMagnificationAnimationCallback mAnimationCallback;
private IWindowMagnificationConnection mIWindowMagnificationConnection;
private WindowMagnification mWindowMagnification;
@@ -92,22 +90,21 @@
@Test
public void enableWindowMagnification_passThrough() throws RemoteException {
mIWindowMagnificationConnection.enableWindowMagnification(TEST_DISPLAY, 3.0f, Float.NaN,
- Float.NaN, mRemoteCallback);
+ Float.NaN, mAnimationCallback);
waitForIdleSync();
verify(mWindowMagnificationAnimationController).enableWindowMagnification(eq(3.0f),
- eq(Float.NaN), eq(Float.NaN), mRunnableCaptor.capture());
- verifyRunnableWrapsRemoteCallback(mRunnableCaptor.getValue());
+ eq(Float.NaN), eq(Float.NaN), eq(mAnimationCallback));
}
@Test
public void disableWindowMagnification_deleteWindowMagnification() throws RemoteException {
- mIWindowMagnificationConnection.disableWindowMagnification(TEST_DISPLAY, mRemoteCallback);
+ mIWindowMagnificationConnection.disableWindowMagnification(TEST_DISPLAY,
+ mAnimationCallback);
waitForIdleSync();
verify(mWindowMagnificationAnimationController).deleteWindowMagnification(
- mRunnableCaptor.capture());
- verifyRunnableWrapsRemoteCallback(mRunnableCaptor.getValue());
+ mAnimationCallback);
}
@Test
@@ -143,10 +140,5 @@
verify(mModeSwitchesController).removeButton(TEST_DISPLAY);
}
-
- private void verifyRunnableWrapsRemoteCallback(Runnable runnable) {
- runnable.run();
- verify(mRemoteCallback).sendResult(null);
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index d74c62b..33b1d94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.never;
@@ -28,9 +29,11 @@
import android.app.Instrumentation;
import android.content.Context;
import android.os.Handler;
+import android.os.RemoteException;
import android.os.SystemClock;
import android.testing.AndroidTestingRunner;
import android.view.SurfaceControl;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.animation.AccelerateInterpolator;
import androidx.test.InstrumentationRegistry;
@@ -75,9 +78,9 @@
@Mock
WindowMagnifierCallback mWindowMagnifierCallback;
@Mock
- Runnable mAnimationEndCallback;
+ IRemoteMagnificationAnimationCallback mAnimationCallback;
@Mock
- Runnable mAnimationEndCallback2;
+ IRemoteMagnificationAnimationCallback mAnimationCallback2;
private SpyWindowMagnificationController mController;
private WindowMagnificationController mSpyController;
private WindowMagnificationAnimationController mWindowMagnificationAnimationController;
@@ -105,8 +108,9 @@
}
@Test
- public void enableWindowMagnification_disabled_expectedValuesAndInvokeCallback() {
- enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationEndCallback);
+ public void enableWindowMagnification_disabled_expectedValuesAndInvokeCallback()
+ throws RemoteException {
+ enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationCallback);
verify(mSpyController, atLeast(2)).enableWindowMagnification(
mScaleCaptor.capture(),
@@ -115,28 +119,30 @@
verifyStartValue(mCenterXCaptor, DEFAULT_CENTER_X);
verifyStartValue(mCenterYCaptor, DEFAULT_CENTER_Y);
verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X, DEFAULT_CENTER_Y);
- verify(mAnimationEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
- public void enableWindowMagnificationWithScaleOne_disabled_NoAnimationAndInvokeCallback() {
+ public void enableWindowMagnificationWithScaleOne_disabled_NoAnimationAndInvokeCallback()
+ throws RemoteException {
mInstrumentation.runOnMainSync(
() -> {
mWindowMagnificationAnimationController.enableWindowMagnification(1,
- DEFAULT_CENTER_X, DEFAULT_CENTER_Y, mAnimationEndCallback);
+ DEFAULT_CENTER_X, DEFAULT_CENTER_Y, mAnimationCallback);
});
SystemClock.sleep(mWaitingAnimationPeriod);
verify(mSpyController).enableWindowMagnification(1, DEFAULT_CENTER_X,
DEFAULT_CENTER_Y);
- verify(mAnimationEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
- public void enableWindowMagnification_enabling_expectedValuesAndInvokeCallback() {
+ public void enableWindowMagnification_enabling_expectedValuesAndInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
- mAnimationEndCallback);
+ mAnimationCallback);
final float targetScale = DEFAULT_SCALE + 1.0f;
final float targetCenterX = DEFAULT_CENTER_X + 100;
final float targetCenterY = DEFAULT_CENTER_Y + 100;
@@ -144,7 +150,7 @@
mInstrumentation.runOnMainSync(() -> {
Mockito.reset(mSpyController);
mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
- targetCenterX, targetCenterY, mAnimationEndCallback2);
+ targetCenterX, targetCenterY, mAnimationCallback2);
mCurrentScale.set(mController.getScale());
mCurrentCenterX.set(mController.getCenterX());
mCurrentCenterY.set(mController.getCenterY());
@@ -158,33 +164,35 @@
verifyStartValue(mCenterXCaptor, mCurrentCenterX.get());
verifyStartValue(mCenterYCaptor, mCurrentCenterY.get());
verifyFinalSpec(targetScale, targetCenterX, targetCenterY);
- verify(mAnimationEndCallback, never()).run();
- verify(mAnimationEndCallback2).run();
+ verify(mAnimationCallback).onResult(false);
+ verify(mAnimationCallback2).onResult(true);
}
@Test
- public void enableWindowMagnificationWithSameSpec_enabling_NoAnimationAndInvokeCallback() {
+ public void enableWindowMagnificationWithSameSpec_enabling_NoAnimationAndInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
- mAnimationEndCallback);
+ mAnimationCallback);
mInstrumentation.runOnMainSync(() -> {
Mockito.reset(mSpyController);
mWindowMagnificationAnimationController.enableWindowMagnification(Float.NaN,
- Float.NaN, Float.NaN, mAnimationEndCallback2);
+ Float.NaN, Float.NaN, mAnimationCallback2);
});
SystemClock.sleep(mWaitingAnimationPeriod);
verify(mSpyController, never()).enableWindowMagnification(anyFloat(), anyFloat(),
anyFloat());
- verify(mAnimationEndCallback, never()).run();
- verify(mAnimationEndCallback2).run();
+ verify(mAnimationCallback).onResult(false);
+ verify(mAnimationCallback2).onResult(true);
}
@Test
- public void enableWindowMagnification_disabling_expectedValuesAndInvokeCallback() {
+ public void enableWindowMagnification_disabling_expectedValuesAndInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, null);
deleteWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
- mAnimationEndCallback);
+ mAnimationCallback);
final float targetScale = DEFAULT_SCALE + 1.0f;
final float targetCenterX = DEFAULT_CENTER_X + 100;
final float targetCenterY = DEFAULT_CENTER_Y + 100;
@@ -193,13 +201,14 @@
() -> {
Mockito.reset(mSpyController);
mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
- targetCenterX, targetCenterY, mAnimationEndCallback2);
+ targetCenterX, targetCenterY, mAnimationCallback2);
mCurrentScale.set(mController.getScale());
mCurrentCenterX.set(mController.getCenterX());
mCurrentCenterY.set(mController.getCenterY());
});
// Current spec shouldn't match given spec.
- verify(mAnimationEndCallback2, never()).run();
+ verify(mAnimationCallback2, never()).onResult(anyBoolean());
+ verify(mAnimationCallback).onResult(false);
SystemClock.sleep(mWaitingAnimationPeriod);
verify(mSpyController, atLeast(2)).enableWindowMagnification(
@@ -213,34 +222,35 @@
assertTrue(mCenterYCaptor.getAllValues().get(0) > mCurrentCenterY.get());
assertEquals(targetCenterY, mCenterYCaptor.getValue(), 0f);
verifyFinalSpec(targetScale, targetCenterX, targetCenterY);
- verify(mAnimationEndCallback, never()).run();
- verify(mAnimationEndCallback2).run();
+ verify(mAnimationCallback2).onResult(true);
}
@Test
- public void enableWindowMagnificationWithSameSpec_disabling_NoAnimationAndInvokeCallback() {
+ public void enableWindowMagnificationWithSameSpec_disabling_NoAnimationAndInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, null);
deleteWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
- mAnimationEndCallback);
+ mAnimationCallback);
mInstrumentation.runOnMainSync(() -> {
Mockito.reset(mSpyController);
mWindowMagnificationAnimationController.enableWindowMagnification(Float.NaN,
- Float.NaN, Float.NaN, mAnimationEndCallback2);
+ Float.NaN, Float.NaN, mAnimationCallback2);
});
SystemClock.sleep(mWaitingAnimationPeriod);
verify(mSpyController, never()).enableWindowMagnification(anyFloat(), anyFloat(),
anyFloat());
verify(mSpyController, never()).deleteWindowMagnification();
- verify(mAnimationEndCallback, never()).run();
- verify(mAnimationEndCallback2).run();
+ verify(mAnimationCallback).onResult(false);
+ verify(mAnimationCallback2).onResult(true);
}
@Test
- public void enableWindowMagnification_enabled_expectedValuesAndInvokeCallback() {
+ public void enableWindowMagnification_enabled_expectedValuesAndInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
- mAnimationEndCallback);
+ mAnimationCallback);
final float targetScale = DEFAULT_SCALE + 1.0f;
final float targetCenterX = DEFAULT_CENTER_X + 100;
final float targetCenterY = DEFAULT_CENTER_Y + 100;
@@ -248,7 +258,7 @@
mInstrumentation.runOnMainSync(() -> {
Mockito.reset(mSpyController);
mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
- targetCenterX, targetCenterY, mAnimationEndCallback2);
+ targetCenterX, targetCenterY, mAnimationCallback2);
mCurrentScale.set(mController.getScale());
mCurrentCenterX.set(mController.getCenterX());
mCurrentCenterY.set(mController.getCenterY());
@@ -262,19 +272,20 @@
verifyStartValue(mCenterXCaptor, mCurrentCenterX.get());
verifyStartValue(mCenterYCaptor, mCurrentCenterY.get());
verifyFinalSpec(targetScale, targetCenterX, targetCenterY);
- verify(mAnimationEndCallback, never()).run();
- verify(mAnimationEndCallback2).run();
+ verify(mAnimationCallback).onResult(false);
+ verify(mAnimationCallback2).onResult(true);
}
@Test
- public void enableWindowMagnificationWithSameScale_enabled_doNothingButInvokeCallback() {
+ public void enableWindowMagnificationWithSameScale_enabled_doNothingButInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, null);
- enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationEndCallback);
+ enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationCallback);
verify(mSpyController, never()).enableWindowMagnification(anyFloat(), anyFloat(),
anyFloat());
- verify(mAnimationEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
@@ -289,10 +300,11 @@
}
@Test
- public void deleteWindowMagnification_enabled_expectedValuesAndInvokeCallback() {
+ public void deleteWindowMagnification_enabled_expectedValuesAndInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, null);
- deleteWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationEndCallback);
+ deleteWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationCallback);
verify(mSpyController, atLeast(2)).enableWindowMagnification(mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture());
@@ -301,27 +313,29 @@
verifyStartValue(mCenterXCaptor, Float.NaN);
verifyStartValue(mCenterYCaptor, Float.NaN);
verifyFinalSpec(Float.NaN, Float.NaN, Float.NaN);
- verify(mAnimationEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
- public void deleteWindowMagnification_disabled_doNothingAndInvokeCallback() {
- deleteWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationEndCallback);
+ public void deleteWindowMagnification_disabled_doNothingAndInvokeCallback()
+ throws RemoteException {
+ deleteWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationCallback);
Mockito.verifyNoMoreInteractions(mSpyController);
- verify(mAnimationEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
- public void deleteWindowMagnification_enabling_expectedValuesAndInvokeCallback() {
+ public void deleteWindowMagnification_enabling_expectedValuesAndInvokeCallback()
+ throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
- mAnimationEndCallback);
+ mAnimationCallback);
mInstrumentation.runOnMainSync(
() -> {
Mockito.reset(mSpyController);
mWindowMagnificationAnimationController.deleteWindowMagnification(
- mAnimationEndCallback2);
+ mAnimationCallback2);
mCurrentScale.set(mController.getScale());
mCurrentCenterX.set(mController.getCenterX());
mCurrentCenterY.set(mController.getCenterY());
@@ -339,25 +353,25 @@
verifyStartValue(mCenterXCaptor, Float.NaN);
verifyStartValue(mCenterYCaptor, Float.NaN);
verifyFinalSpec(Float.NaN, Float.NaN, Float.NaN);
- verify(mAnimationEndCallback, never()).run();
- verify(mAnimationEndCallback2).run();
+ verify(mAnimationCallback).onResult(false);
+ verify(mAnimationCallback2).onResult(true);
}
@Test
- public void deleteWindowMagnification_disabling_checkStartAndValues() {
+ public void deleteWindowMagnification_disabling_checkStartAndValues() throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, null);
deleteWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
- mAnimationEndCallback);
+ mAnimationCallback);
- deleteWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationEndCallback2);
+ deleteWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, mAnimationCallback2);
verify(mSpyController, atLeast(2)).enableWindowMagnification(mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture());
verify(mSpyController).deleteWindowMagnification();
assertEquals(1.0f, mScaleCaptor.getValue(), 0f);
verifyFinalSpec(Float.NaN, Float.NaN, Float.NaN);
- verify(mAnimationEndCallback, never()).run();
- verify(mAnimationEndCallback2).run();
+ verify(mAnimationCallback).onResult(false);
+ verify(mAnimationCallback2).onResult(true);
}
@Test
@@ -386,22 +400,22 @@
}
private void enableWindowMagnificationAndWaitAnimating(long duration,
- @Nullable Runnable endCallback) {
+ @Nullable IRemoteMagnificationAnimationCallback callback) {
mInstrumentation.runOnMainSync(
() -> {
Mockito.reset(mSpyController);
mWindowMagnificationAnimationController.enableWindowMagnification(DEFAULT_SCALE,
- DEFAULT_CENTER_X, DEFAULT_CENTER_Y, endCallback);
+ DEFAULT_CENTER_X, DEFAULT_CENTER_Y, callback);
});
SystemClock.sleep(duration);
}
private void deleteWindowMagnificationAndWaitAnimating(long duration,
- @Nullable Runnable endCallback) {
+ @Nullable IRemoteMagnificationAnimationCallback callback) {
mInstrumentation.runOnMainSync(
() -> {
resetMockObjects();
- mWindowMagnificationAnimationController.deleteWindowMagnification(endCallback);
+ mWindowMagnificationAnimationController.deleteWindowMagnification(callback);
});
SystemClock.sleep(duration);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
index a401bcd3..993027d 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
@@ -20,11 +20,12 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.RemoteCallback;
import android.os.RemoteException;
import android.util.Slog;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
+import android.view.accessibility.MagnificationAnimationCallback;
/**
* A wrapper of {@link IWindowMagnificationConnection}.
@@ -50,9 +51,10 @@
}
boolean enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
- @Nullable RemoteCallback endCallback) {
+ @Nullable MagnificationAnimationCallback callback) {
try {
- mConnection.enableWindowMagnification(displayId, scale, centerX, centerY, endCallback);
+ mConnection.enableWindowMagnification(displayId, scale, centerX, centerY,
+ transformToRemoteCallback(callback));
} catch (RemoteException e) {
if (DBG) {
Slog.e(TAG, "Error calling enableWindowMagnification()", e);
@@ -74,9 +76,10 @@
return true;
}
- boolean disableWindowMagnification(int displayId, @Nullable RemoteCallback endCallback) {
+ boolean disableWindowMagnification(int displayId,
+ @Nullable MagnificationAnimationCallback callback) {
try {
- mConnection.disableWindowMagnification(displayId, endCallback);
+ mConnection.disableWindowMagnification(displayId, transformToRemoteCallback(callback));
} catch (RemoteException e) {
if (DBG) {
Slog.e(TAG, "Error calling disableWindowMagnification()", e);
@@ -134,4 +137,27 @@
return true;
}
+ private static @Nullable
+ IRemoteMagnificationAnimationCallback transformToRemoteCallback(
+ MagnificationAnimationCallback callback) {
+ if (callback == null) {
+ return null;
+ }
+ return new RemoteAnimationCallback(callback);
+ }
+
+ private static class RemoteAnimationCallback extends
+ IRemoteMagnificationAnimationCallback.Stub {
+
+ private final MagnificationAnimationCallback mCallback;
+
+ RemoteAnimationCallback(@NonNull MagnificationAnimationCallback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public void onResult(boolean success) throws RemoteException {
+ mCallback.onResult(success);
+ }
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index d3d56d7..d78d99e 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -24,7 +24,6 @@
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
-import android.os.RemoteCallback;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.MathUtils;
@@ -33,6 +32,7 @@
import android.view.MotionEvent;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
+import android.view.accessibility.MagnificationAnimationCallback;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -234,17 +234,17 @@
* or {@link Float#NaN} to leave unchanged.
* @param centerY The screen-relative Y coordinate around which to center,
* or {@link Float#NaN} to leave unchanged.
- * @param endCallback Called when the animation is ended without any interruption or the
- * window magnifier is disabled already.
+ * @param animationCallback Called when the animation result is valid.
*/
void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
- @Nullable Runnable endCallback) {
+ @Nullable MagnificationAnimationCallback animationCallback) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
magnifier = createWindowMagnifier(displayId);
}
- magnifier.enableWindowMagnificationInternal(scale, centerX, centerY, endCallback);
+ magnifier.enableWindowMagnificationInternal(scale, centerX, centerY,
+ animationCallback);
}
}
@@ -263,16 +263,16 @@
*
* @param displayId The logical display id.
* @param clear {@true} Clears the state of window magnification.
- * @param endCallback Called when the animation is ended without any interruption or the
- * window magnifier is disabled already.
+ * @param animationCallback Called when the animation result is valid.
*/
- void disableWindowMagnification(int displayId, boolean clear, Runnable endCallback) {
+ void disableWindowMagnification(int displayId, boolean clear,
+ MagnificationAnimationCallback animationCallback) {
synchronized (mLock) {
WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
if (magnifier == null) {
return;
}
- magnifier.disableWindowMagnificationInternal(endCallback);
+ magnifier.disableWindowMagnificationInternal(animationCallback);
if (clear) {
mWindowMagnifiers.delete(displayId);
}
@@ -481,22 +481,23 @@
@GuardedBy("mLock")
void enableWindowMagnificationInternal(float scale, float centerX, float centerY,
- @Nullable Runnable endCallback) {
+ @Nullable MagnificationAnimationCallback animationCallback) {
if (mEnabled) {
return;
}
final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
if (mWindowMagnificationManager.enableWindowMagnificationInternal(mDisplayId, normScale,
- centerX, centerY, endCallback)) {
+ centerX, centerY, animationCallback)) {
mScale = normScale;
mEnabled = true;
}
}
@GuardedBy("mLock")
- void disableWindowMagnificationInternal(@Nullable Runnable endCallback) {
+ void disableWindowMagnificationInternal(
+ @Nullable MagnificationAnimationCallback animationResultCallback) {
if (mEnabled && mWindowMagnificationManager.disableWindowMagnificationInternal(
- mDisplayId, endCallback)) {
+ mDisplayId, animationResultCallback)) {
mEnabled = false;
}
}
@@ -558,20 +559,19 @@
}
private boolean enableWindowMagnificationInternal(int displayId, float scale, float centerX,
- float centerY, Runnable endCallback) {
+ float centerY, MagnificationAnimationCallback animationCallback) {
return mConnectionWrapper != null && mConnectionWrapper.enableWindowMagnification(
- displayId, scale, centerX, centerY,
- endCallback != null ? new RemoteCallback(bundle -> endCallback.run()) : null);
+ displayId, scale, centerX, centerY, animationCallback);
}
private boolean setScaleInternal(int displayId, float scale) {
return mConnectionWrapper != null && mConnectionWrapper.setScale(displayId, scale);
}
- private boolean disableWindowMagnificationInternal(int displayId, Runnable endCallback) {
+ private boolean disableWindowMagnificationInternal(int displayId,
+ MagnificationAnimationCallback animationCallback) {
return mConnectionWrapper != null && mConnectionWrapper.disableWindowMagnification(
- displayId,
- endCallback != null ? new RemoteCallback(bundle -> endCallback.run()) : null);
+ displayId, animationCallback);
}
private boolean moveWindowMagnifierInternal(int displayId, float offsetX, float offsetY) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java
index f896d75..10322e7 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java
@@ -28,9 +28,9 @@
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
-import android.os.RemoteCallback;
import android.os.RemoteException;
import android.view.Display;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
@@ -38,7 +38,7 @@
* Mocks the basic logic of window magnification in System UI. We assume the screen size is
* unlimited, so source bounds is always on the center of the mirror window bounds.
*/
-class MockWindowMagnificationConnection {
+class MockWindowMagnificationConnection {
public static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
private final IWindowMagnificationConnection mConnection;
@@ -72,27 +72,30 @@
throw new IllegalArgumentException("only support default display :" + displayId);
}
computeMirrorWindowFrame(invocation.getArgument(2), invocation.getArgument(3));
- final RemoteCallback callback = invocation.getArgument(4);
+ final IRemoteMagnificationAnimationCallback callback = invocation.getArgument(4);
if (callback != null) {
- callback.sendResult(null);
+ callback.onResult(true);
}
- mIMirrorWindowCallback.onWindowMagnifierBoundsChanged(TEST_DISPLAY,
- mMirrorWindowFrame);
+ if (mIMirrorWindowCallback != null) {
+ mIMirrorWindowCallback.onWindowMagnifierBoundsChanged(TEST_DISPLAY,
+ mMirrorWindowFrame);
+ }
return null;
- }).when(mConnection).enableWindowMagnification(anyInt(),
- anyFloat(), anyFloat(), anyFloat(), nullable(RemoteCallback.class));
+ }).when(mConnection).enableWindowMagnification(anyInt(), anyFloat(), anyFloat(), anyFloat(),
+ nullable(IRemoteMagnificationAnimationCallback.class));
doAnswer((invocation) -> {
final int displayId = invocation.getArgument(0);
if (displayId != TEST_DISPLAY) {
throw new IllegalArgumentException("only support default display :" + displayId);
}
- final RemoteCallback callback = invocation.getArgument(1);
+ final IRemoteMagnificationAnimationCallback callback = invocation.getArgument(1);
if (callback != null) {
- callback.sendResult(null);
+ callback.onResult(true);
}
return null;
- }).when(mConnection).disableWindowMagnification(anyInt(), nullable(RemoteCallback.class));
+ }).when(mConnection).disableWindowMagnification(anyInt(),
+ nullable(IRemoteMagnificationAnimationCallback.class));
}
private void computeMirrorWindowFrame(float centerX, float centerY) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
index 9ef65d9..c88bc3b 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
@@ -17,14 +17,17 @@
package com.android.server.accessibility.magnification;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
-import android.os.RemoteCallback;
import android.os.RemoteException;
import android.provider.Settings;
import android.view.Display;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
+import android.view.accessibility.MagnificationAnimationCallback;
import org.junit.Before;
import org.junit.Test;
@@ -40,26 +43,29 @@
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
- @Mock
private IWindowMagnificationConnection mConnection;
@Mock
private IWindowMagnificationConnectionCallback mCallback;
@Mock
- private RemoteCallback.OnResultListener mOnResultListener;
- private RemoteCallback mRemoteCallback;
+ private MagnificationAnimationCallback mAnimationCallback;
+
+ private MockWindowMagnificationConnection mMockWindowMagnificationConnection;
private WindowMagnificationConnectionWrapper mConnectionWrapper;
@Before
- public void setUp() {
+ public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
+ mMockWindowMagnificationConnection = new MockWindowMagnificationConnection();
+ mConnection = mMockWindowMagnificationConnection.getConnection();
mConnectionWrapper = new WindowMagnificationConnectionWrapper(mConnection);
- mRemoteCallback = new RemoteCallback(mOnResultListener);
}
@Test
public void enableWindowMagnification() throws RemoteException {
- mConnectionWrapper.enableWindowMagnification(TEST_DISPLAY, 2, 100f, 200f, mRemoteCallback);
- verify(mConnection).enableWindowMagnification(TEST_DISPLAY, 2, 100f, 200f, mRemoteCallback);
+ mConnectionWrapper.enableWindowMagnification(TEST_DISPLAY, 2, 100f, 200f,
+ mAnimationCallback);
+
+ verify(mAnimationCallback).onResult(true);
}
@Test
@@ -70,8 +76,11 @@
@Test
public void disableWindowMagnification() throws RemoteException {
- mConnectionWrapper.disableWindowMagnification(TEST_DISPLAY, mRemoteCallback);
- verify(mConnection).disableWindowMagnification(TEST_DISPLAY, mRemoteCallback);
+ mConnectionWrapper.disableWindowMagnification(TEST_DISPLAY, mAnimationCallback);
+
+ verify(mConnection).disableWindowMagnification(eq(TEST_DISPLAY),
+ any(IRemoteMagnificationAnimationCallback.class));
+ verify(mAnimationCallback).onResult(true);
}
@Test
@@ -99,5 +108,4 @@
mConnectionWrapper.setConnectionCallback(mCallback);
verify(mConnection).setConnectionCallback(mCallback);
}
-
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index dcb1262..9366e95 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -48,6 +48,7 @@
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
+import android.view.accessibility.MagnificationAnimationCallback;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
@@ -73,7 +74,7 @@
@Mock
private StatusBarManagerInternal mMockStatusBarManagerInternal;
@Mock
- private Runnable mEndCallback;
+ private MagnificationAnimationCallback mAnimationCallback;
private MockContentResolver mResolver;
private WindowMagnificationManager mWindowMagnificationManager;
@@ -177,9 +178,9 @@
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, 200f, 300f,
- mEndCallback);
+ mAnimationCallback);
- verify(mEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test
@@ -198,9 +199,10 @@
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
- mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false, mEndCallback);
+ mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false,
+ mAnimationCallback);
- verify(mEndCallback).run();
+ verify(mAnimationCallback).onResult(true);
}
@Test