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.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
|
||||||
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
|
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.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.ActivityTaskManager;
|
import android.app.ActivityTaskManager;
|
||||||
@@ -223,14 +220,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
|
|
||||||
private void initAnimation(MotionEvent event) {
|
private void initAnimation(MotionEvent event) {
|
||||||
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "initAnimation mMotionStarted=%b", mBackGestureStarted);
|
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.");
|
Log.e(TAG, "Animation is being initialized but is already started.");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBackNavigationInfo != null) {
|
|
||||||
finishAnimation();
|
finishAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
mInitTouchLocation.set(event.getX(), event.getY());
|
mInitTouchLocation.set(event.getX(), event.getY());
|
||||||
mBackGestureStarted = true;
|
mBackGestureStarted = true;
|
||||||
|
|
||||||
@@ -304,8 +298,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int deltaX = Math.round(event.getX() - mInitTouchLocation.x);
|
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 progressThreshold = PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold;
|
||||||
float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1);
|
float progress = Math.min(Math.max(Math.abs(deltaX) / progressThreshold, 0), 1);
|
||||||
int backType = mBackNavigationInfo.getType();
|
int backType = mBackNavigationInfo.getType();
|
||||||
@@ -317,11 +309,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
targetCallback = mBackToLauncherCallback;
|
targetCallback = mBackToLauncherCallback;
|
||||||
} else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
|
} else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
|
||||||
|| backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
|
|| backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
|
||||||
if (animationTarget != null) {
|
// TODO(208427216) Run the actual animation
|
||||||
mTransaction.setPosition(animationTarget.leash, deltaX, deltaY);
|
|
||||||
mTouchEventDelta.set(deltaX, deltaY);
|
|
||||||
mTransaction.apply();
|
|
||||||
}
|
|
||||||
} else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
|
} else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
|
||||||
targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
|
targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
|
||||||
}
|
}
|
||||||
@@ -343,19 +331,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
} else {
|
} else {
|
||||||
dispatchOnBackCancelled(targetCallback);
|
dispatchOnBackCancelled(targetCallback);
|
||||||
}
|
}
|
||||||
if (backType == BackNavigationInfo.TYPE_CALLBACK) {
|
if (backType != BackNavigationInfo.TYPE_RETURN_TO_HOME || !shouldDispatchToLauncher) {
|
||||||
finishAnimation();
|
|
||||||
} else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
|
|
||||||
&& !shouldDispatchToLauncher) {
|
|
||||||
// Launcher callback missing. Simply finish animation.
|
// Launcher callback missing. Simply finish animation.
|
||||||
finishAnimation();
|
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(
|
private static void dispatchOnBackProgressed(IOnBackInvokedCallback callback,
|
||||||
IOnBackInvokedCallback callback, BackEvent backEvent) {
|
BackEvent backEvent) {
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
return;
|
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.
|
* Sets to true when the back gesture has passed the triggering threshold, false otherwise.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,10 +16,16 @@
|
|||||||
|
|
||||||
package com.android.wm.shell.back;
|
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.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.atLeastOnce;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.app.IActivityTaskManager;
|
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() {
|
RemoteAnimationTarget createAnimationTarget() {
|
||||||
SurfaceControl topWindowLeash = new SurfaceControl();
|
SurfaceControl topWindowLeash = new SurfaceControl();
|
||||||
return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
|
return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
|
||||||
@@ -109,6 +123,18 @@ public class BackAnimationControllerTest {
|
|||||||
true, null, null, null, false, -1);
|
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
|
@Test
|
||||||
@Ignore("b/207481538")
|
@Ignore("b/207481538")
|
||||||
public void crossActivity_screenshotAttachedAndVisible() {
|
public void crossActivity_screenshotAttachedAndVisible() {
|
||||||
@@ -140,10 +166,31 @@ public class BackAnimationControllerTest {
|
|||||||
MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
|
MotionEvent.obtain(10, 0, MotionEvent.ACTION_MOVE, 100, 100, 0),
|
||||||
MotionEvent.ACTION_MOVE,
|
MotionEvent.ACTION_MOVE,
|
||||||
BackEvent.EDGE_LEFT);
|
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();
|
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
|
@Test
|
||||||
public void backToHome_dispatchesEvents() throws RemoteException {
|
public void backToHome_dispatchesEvents() throws RemoteException {
|
||||||
mController.setBackToLauncherCallback(mIOnBackInvokedCallback);
|
mController.setBackToLauncherCallback(mIOnBackInvokedCallback);
|
||||||
|
|||||||
Reference in New Issue
Block a user