Merge "Ensure no animation is run except for HOME" into tm-dev

This commit is contained in:
Vadim Caen
2022-04-01 09:23:26 +00:00
committed by Android (Google) Code Review
2 changed files with 54 additions and 71 deletions

View File

@@ -19,9 +19,6 @@ package com.android.wm.shell.back;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
@@ -223,14 +220,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
private void initAnimation(MotionEvent event) {
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "initAnimation mMotionStarted=%b", mBackGestureStarted);
if (mBackGestureStarted) {
if (mBackGestureStarted || mBackNavigationInfo != null) {
Log.e(TAG, "Animation is being initialized but is already started.");
return;
}
if (mBackNavigationInfo != null) {
finishAnimation();
}
mInitTouchLocation.set(event.getX(), event.getY());
mBackGestureStarted = true;
@@ -304,8 +298,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
return;
}
int deltaX = Math.round(event.getX() - mInitTouchLocation.x);
int deltaY = Math.round(event.getY() - mInitTouchLocation.y);
ProtoLog.v(WM_SHELL_BACK_PREVIEW, "Runner move: %d %d", deltaX, deltaY);
float progressThreshold = PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold;
float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1);
int backType = mBackNavigationInfo.getType();
@@ -317,11 +309,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
targetCallback = mBackToLauncherCallback;
} else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
|| backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
if (animationTarget != null) {
mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
mTouchEventDelta.set(deltaX, deltaY);
mTransaction.apply();
}
// TODO(208427216) Run the actual animation
} else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
}
@@ -343,19 +331,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
} else {
dispatchOnBackCancelled(targetCallback);
}
if (backType == BackNavigationInfo.TYPE_CALLBACK) {
finishAnimation();
} else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
&& !shouldDispatchToLauncher) {
if (backType != BackNavigationInfo.TYPE_RETURN_TO_HOME || !shouldDispatchToLauncher) {
// Launcher callback missing. Simply finish animation.
finishAnimation();
} else if (backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY
|| backType == BackNavigationInfo.TYPE_CROSS_TASK) {
if (mTriggerBack) {
prepareTransition();
} else {
resetPositionAnimated();
}
}
}
@@ -403,8 +381,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
private static void dispatchOnBackProgressed(
IOnBackInvokedCallback callback, BackEvent backEvent) {
private static void dispatchOnBackProgressed(IOnBackInvokedCallback callback,
BackEvent backEvent) {
if (callback == null) {
return;
}
@@ -415,48 +393,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
/**
* Animate the top window leash to its initial position.
*/
private void resetPositionAnimated() {
mBackGestureStarted = false;
// TODO(208786853) Handle overlap with a new coming gesture.
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Runner: Back not triggered, cancelling animation "
+ "mLastPos=%s mInitTouch=%s", mTouchEventDelta, mInitTouchLocation);
// TODO(208427216) : Replace placeholder animation with an actual one.
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f).setDuration(200);
animation.addUpdateListener(animation1 -> {
if (mBackNavigationInfo == null) {
return;
}
float fraction = animation1.getAnimatedFraction();
int deltaX = Math.round(mTouchEventDelta.x - (mTouchEventDelta.x * fraction));
int deltaY = Math.round(mTouchEventDelta.y - (mTouchEventDelta.y * fraction));
RemoteAnimationTarget animationTarget =
mBackNavigationInfo.getDepartingAnimationTarget();
if (animationTarget != null) {
mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
mTransaction.apply();
}
});
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: onAnimationEnd");
finishAnimation();
}
});
animation.start();
}
private void prepareTransition() {
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "prepareTransition()");
mTriggerBack = false;
mBackGestureStarted = false;
}
/**
* Sets to true when the back gesture has passed the triggering threshold, false otherwise.
*/

View File

@@ -16,10 +16,16 @@
package com.android.wm.shell.back;
import static android.window.BackNavigationInfo.KEY_TRIGGER_BACK;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.app.IActivityTaskManager;
@@ -101,6 +107,14 @@ public class BackAnimationControllerTest {
}
}
private void createNavigationInfo(BackNavigationInfo.Builder builder) {
try {
doReturn(builder.build()).when(mActivityTaskManager).startBackNavigation();
} catch (RemoteException ex) {
ex.rethrowFromSystemServer();
}
}
RemoteAnimationTarget createAnimationTarget() {
SurfaceControl topWindowLeash = new SurfaceControl();
return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
@@ -109,6 +123,18 @@ public class BackAnimationControllerTest {
true, null, null, null, false, -1);
}
private void triggerBackGesture() {
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0);
mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
mController.setTriggerBack(true);
event = MotionEvent.obtain(10, 0, MotionEvent.ACTION_UP, 100, 100, 0);
mController.onMotionEvent(event, event.getAction(), BackEvent.EDGE_LEFT);
}
@Test
@Ignore("b/207481538")
public void crossActivity_screenshotAttachedAndVisible() {
@@ -140,10 +166,31 @@ public class BackAnimationControllerTest {
MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
MotionEvent.ACTION_MOVE,
BackEvent.EDGE_LEFT);
verify(mTransaction).setPosition(animationTarget.leash, 100, 100);
// b/207481538, we check that the surface is not moved for now, we can re-enable this once
// we implement the animation
verify(mTransaction, never()).setScale(eq(screenshotSurface), anyInt(), anyInt());
verify(mTransaction, never()).setPosition(animationTarget.leash, 100, 100);
verify(mTransaction, atLeastOnce()).apply();
}
@Test
public void verifyAnimationFinishes() {
RemoteAnimationTarget animationTarget = createAnimationTarget();
boolean[] backNavigationDone = new boolean[]{false};
boolean[] triggerBack = new boolean[]{false};
createNavigationInfo(new BackNavigationInfo.Builder()
.setDepartingAnimationTarget(animationTarget)
.setType(BackNavigationInfo.TYPE_CROSS_ACTIVITY)
.setOnBackNavigationDone(
new RemoteCallback(result -> {
backNavigationDone[0] = true;
triggerBack[0] = result.getBoolean(KEY_TRIGGER_BACK);
})));
triggerBackGesture();
assertTrue("Navigation Done callback not called", backNavigationDone[0]);
assertTrue("TriggerBack should have been true", triggerBack[0]);
}
@Test
public void backToHome_dispatchesEvents() throws RemoteException {
mController.setBackToLauncherCallback(mIOnBackInvokedCallback);