Merge "Ensure no animation is run except for HOME" into tm-dev
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user