Merge "Fix no back animations when the target window is animating" into udc-dev
This commit is contained in:
@@ -271,6 +271,12 @@
|
||||
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
|
||||
"at": "com\/android\/server\/wm\/AppTransition.java"
|
||||
},
|
||||
"-1868518158": {
|
||||
"message": "Pending back animation due to another animation is running",
|
||||
"level": "WARN",
|
||||
"group": "WM_DEBUG_BACK_PREVIEW",
|
||||
"at": "com\/android\/server\/wm\/BackNavigationController.java"
|
||||
},
|
||||
"-1868124841": {
|
||||
"message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b",
|
||||
"level": "VERBOSE",
|
||||
@@ -1549,6 +1555,12 @@
|
||||
"group": "WM_DEBUG_ORIENTATION",
|
||||
"at": "com\/android\/server\/wm\/DragState.java"
|
||||
},
|
||||
"-692907078": {
|
||||
"message": "Handling the deferred animation after transition finished",
|
||||
"level": "DEBUG",
|
||||
"group": "WM_DEBUG_BACK_PREVIEW",
|
||||
"at": "com\/android\/server\/wm\/BackNavigationController.java"
|
||||
},
|
||||
"-677449371": {
|
||||
"message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
|
||||
"level": "DEBUG",
|
||||
|
||||
@@ -552,6 +552,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
if (runner.isWaitingAnimation()) {
|
||||
ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready.");
|
||||
return;
|
||||
} else if (runner.isAnimationCancelled()) {
|
||||
invokeOrCancelBack();
|
||||
return;
|
||||
}
|
||||
startPostCommitAnimation();
|
||||
}
|
||||
@@ -653,7 +656,19 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancelled() { }
|
||||
public void onAnimationCancelled() {
|
||||
mShellExecutor.execute(() -> {
|
||||
final BackAnimationRunner runner = mAnimationDefinition.get(
|
||||
mBackNavigationInfo.getType());
|
||||
if (runner == null) {
|
||||
return;
|
||||
}
|
||||
runner.cancelAnimation();
|
||||
if (!mBackGestureStarted) {
|
||||
invokeOrCancelBack();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
mBackAnimationAdapter = new BackAnimationAdapter(runner);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ class BackAnimationRunner {
|
||||
// Whether we are waiting to receive onAnimationStart
|
||||
private boolean mWaitingAnimation;
|
||||
|
||||
/** True when the back animation is cancelled */
|
||||
private boolean mAnimationCancelled;
|
||||
|
||||
BackAnimationRunner(@NonNull IOnBackInvokedCallback callback,
|
||||
@NonNull IRemoteAnimationRunner runner) {
|
||||
mCallback = callback;
|
||||
@@ -81,9 +84,19 @@ class BackAnimationRunner {
|
||||
|
||||
void startGesture() {
|
||||
mWaitingAnimation = true;
|
||||
mAnimationCancelled = false;
|
||||
}
|
||||
|
||||
boolean isWaitingAnimation() {
|
||||
return mWaitingAnimation;
|
||||
}
|
||||
|
||||
void cancelAnimation() {
|
||||
mWaitingAnimation = false;
|
||||
mAnimationCancelled = true;
|
||||
}
|
||||
|
||||
boolean isAnimationCancelled() {
|
||||
return mAnimationCancelled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,11 @@ class BackNavigationController {
|
||||
private final ArrayList<WindowContainer> mTmpOpenApps = new ArrayList<>();
|
||||
private final ArrayList<WindowContainer> mTmpCloseApps = new ArrayList<>();
|
||||
|
||||
// This will be set if the back navigation is in progress and the current transition is still
|
||||
// running. The pending animation builder will do the animation stuff includes creating leashes,
|
||||
// re-parenting leashes and set launch behind, etc. Will be handled when transition finished.
|
||||
private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder;
|
||||
|
||||
/**
|
||||
* true if the back predictability feature is enabled
|
||||
*/
|
||||
@@ -305,25 +310,26 @@ class BackNavigationController {
|
||||
|| backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY)
|
||||
&& adapter != null;
|
||||
|
||||
// Only prepare animation if no leash has been created (no animation is running).
|
||||
// TODO(b/241808055): Cancel animation when preparing back animation.
|
||||
if (prepareAnimation
|
||||
&& (removedWindowContainer.hasCommittedReparentToAnimationLeash()
|
||||
|| removedWindowContainer.mTransitionController.inTransition())) {
|
||||
Slog.w(TAG, "Can't prepare back animation due to another animation is running.");
|
||||
prepareAnimation = false;
|
||||
}
|
||||
|
||||
if (prepareAnimation) {
|
||||
mPendingAnimation = mAnimationHandler.scheduleAnimation(backType, adapter,
|
||||
currentTask, prevTask, currentActivity, prevActivity);
|
||||
prepareAnimation = mPendingAnimation != null;
|
||||
mBackAnimationInProgress = prepareAnimation;
|
||||
if (prepareAnimation) {
|
||||
mWindowManagerService.mWindowPlacerLocked.requestTraversal();
|
||||
if (mShowWallpaper) {
|
||||
currentTask.getDisplayContent().mWallpaperController
|
||||
.adjustWallpaperWindows();
|
||||
final AnimationHandler.ScheduleAnimationBuilder builder =
|
||||
mAnimationHandler.prepareAnimation(backType, adapter,
|
||||
currentTask, prevTask, currentActivity, prevActivity);
|
||||
mBackAnimationInProgress = builder != null;
|
||||
if (mBackAnimationInProgress) {
|
||||
if (removedWindowContainer.hasCommittedReparentToAnimationLeash()
|
||||
|| removedWindowContainer.mTransitionController.inTransition()
|
||||
|| mWindowManagerService.mSyncEngine.hasPendingSyncSets()) {
|
||||
ProtoLog.w(WM_DEBUG_BACK_PREVIEW,
|
||||
"Pending back animation due to another animation is running");
|
||||
mPendingAnimationBuilder = builder;
|
||||
// Current transition is still running, we have to defer the hiding to the
|
||||
// client process to prevent the unexpected relayout when handling the back
|
||||
// animation.
|
||||
if (prevActivity != null) {
|
||||
prevActivity.setDeferHidingClient(true);
|
||||
}
|
||||
} else {
|
||||
scheduleAnimation(builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -345,6 +351,15 @@ class BackNavigationController {
|
||||
return isWaitBackTransition() || mNavigationMonitor.isMonitoring();
|
||||
}
|
||||
|
||||
private void scheduleAnimation(@NonNull AnimationHandler.ScheduleAnimationBuilder builder) {
|
||||
mPendingAnimation = builder.build();
|
||||
mWindowManagerService.mWindowPlacerLocked.requestTraversal();
|
||||
if (mShowWallpaper) {
|
||||
mWindowManagerService.getDefaultDisplayContentLocked().mWallpaperController
|
||||
.adjustWallpaperWindows();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWaitBackTransition() {
|
||||
return mAnimationHandler.mComposed && mAnimationHandler.mWaitTransition;
|
||||
}
|
||||
@@ -526,6 +541,57 @@ class BackNavigationController {
|
||||
mAnimationHandler.clearBackAnimateTarget(cleanupTransaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the pending animation when the running transition finished.
|
||||
* @param targets The final animation targets derived in transition.
|
||||
*/
|
||||
boolean handleDeferredBackAnimation(@NonNull ArrayList<Transition.ChangeInfo> targets) {
|
||||
if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
|
||||
"Handling the deferred animation after transition finished");
|
||||
|
||||
// Show the target surface and its parents to prevent it or its parents hidden when
|
||||
// the transition finished.
|
||||
// The target could be affected by transition when :
|
||||
// Open transition -> the open target in back navigation
|
||||
// Close transition -> the close target in back navigation.
|
||||
boolean hasTarget = false;
|
||||
final SurfaceControl.Transaction t =
|
||||
mPendingAnimationBuilder.mCloseTarget.getPendingTransaction();
|
||||
for (int i = 0; i < targets.size(); i++) {
|
||||
final WindowContainer wc = targets.get(i).mContainer;
|
||||
if (wc.asActivityRecord() == null && wc.asTask() == null) {
|
||||
continue;
|
||||
} else if (!mPendingAnimationBuilder.containTarget(wc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hasTarget = true;
|
||||
t.show(wc.getSurfaceControl());
|
||||
}
|
||||
|
||||
if (!hasTarget) {
|
||||
// Skip if no target participated in current finished transition.
|
||||
Slog.w(TAG, "Finished transition didn't include the targets"
|
||||
+ " open: " + mPendingAnimationBuilder.mOpenTarget
|
||||
+ " close: " + mPendingAnimationBuilder.mCloseTarget);
|
||||
try {
|
||||
mPendingAnimationBuilder.mBackAnimationAdapter.getRunner().onAnimationCancelled();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
mPendingAnimationBuilder = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
scheduleAnimation(mPendingAnimationBuilder);
|
||||
mPendingAnimationBuilder = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and handling animations status for an open/close animation targets.
|
||||
*/
|
||||
@@ -638,6 +704,7 @@ class BackNavigationController {
|
||||
if (open) {
|
||||
return wc == mOpenAdaptor.mTarget || mOpenAdaptor.mTarget.hasChild(wc);
|
||||
}
|
||||
|
||||
if (mSwitchType == TASK_SWITCH) {
|
||||
return wc == mCloseAdaptor.mTarget
|
||||
|| (wc.asTask() != null && wc.hasChild(mCloseAdaptor.mTarget));
|
||||
@@ -841,23 +908,22 @@ class BackNavigationController {
|
||||
}
|
||||
}
|
||||
|
||||
Runnable scheduleAnimation(int backType, BackAnimationAdapter adapter,
|
||||
ScheduleAnimationBuilder prepareAnimation(int backType, BackAnimationAdapter adapter,
|
||||
Task currentTask, Task previousTask, ActivityRecord currentActivity,
|
||||
ActivityRecord previousActivity) {
|
||||
switch (backType) {
|
||||
case BackNavigationInfo.TYPE_RETURN_TO_HOME:
|
||||
return new ScheduleAnimationBuilder(backType, adapter)
|
||||
.setIsLaunchBehind(true)
|
||||
.setComposeTarget(currentTask, previousTask)
|
||||
.build();
|
||||
.setComposeTarget(currentTask, previousTask);
|
||||
case BackNavigationInfo.TYPE_CROSS_ACTIVITY:
|
||||
return new ScheduleAnimationBuilder(backType, adapter)
|
||||
.setComposeTarget(currentActivity, previousActivity)
|
||||
.setOpeningSnapshot(getActivitySnapshot(previousActivity)).build();
|
||||
.setOpeningSnapshot(getActivitySnapshot(previousActivity));
|
||||
case BackNavigationInfo.TYPE_CROSS_TASK:
|
||||
return new ScheduleAnimationBuilder(backType, adapter)
|
||||
.setComposeTarget(currentTask, previousTask)
|
||||
.setOpeningSnapshot(getTaskSnapshot(previousTask)).build();
|
||||
.setOpeningSnapshot(getTaskSnapshot(previousTask));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -891,6 +957,11 @@ class BackNavigationController {
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean containTarget(@NonNull WindowContainer wc) {
|
||||
return wc == mOpenTarget || wc == mCloseTarget
|
||||
|| wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget);
|
||||
}
|
||||
|
||||
Runnable build() {
|
||||
if (mOpenTarget == null || mCloseTarget == null) {
|
||||
return null;
|
||||
@@ -967,49 +1038,43 @@ class BackNavigationController {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setLaunchBehind(ActivityRecord activity) {
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
if (!activity.isVisibleRequested()) {
|
||||
activity.setVisibility(true);
|
||||
}
|
||||
activity.mLaunchTaskBehind = true;
|
||||
|
||||
// Handle fixed rotation launching app.
|
||||
final DisplayContent dc = activity.mDisplayContent;
|
||||
dc.rotateInDifferentOrientationIfNeeded(activity);
|
||||
if (activity.hasFixedRotationTransform()) {
|
||||
// Set the record so we can recognize it to continue to update display
|
||||
// orientation if the previous activity becomes the top later.
|
||||
dc.setFixedRotationLaunchingApp(activity,
|
||||
activity.getWindowConfiguration().getRotation());
|
||||
}
|
||||
|
||||
ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
|
||||
"Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity);
|
||||
activity.mTaskSupervisor.mStoppingActivities.remove(activity);
|
||||
activity.getDisplayContent().ensureActivitiesVisible(null /* starting */,
|
||||
0 /* configChanges */, false /* preserveWindows */, true);
|
||||
}
|
||||
private void restoreLaunchBehind(ActivityRecord activity) {
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
|
||||
|
||||
// Restore the launch-behind state.
|
||||
activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
|
||||
activity.mLaunchTaskBehind = false;
|
||||
ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
|
||||
"Setting Activity.mLauncherTaskBehind to false. Activity=%s",
|
||||
activity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setLaunchBehind(@NonNull ActivityRecord activity) {
|
||||
if (!activity.isVisibleRequested()) {
|
||||
activity.setVisibility(true);
|
||||
}
|
||||
activity.mLaunchTaskBehind = true;
|
||||
|
||||
// Handle fixed rotation launching app.
|
||||
final DisplayContent dc = activity.mDisplayContent;
|
||||
dc.rotateInDifferentOrientationIfNeeded(activity);
|
||||
if (activity.hasFixedRotationTransform()) {
|
||||
// Set the record so we can recognize it to continue to update display
|
||||
// orientation if the previous activity becomes the top later.
|
||||
dc.setFixedRotationLaunchingApp(activity,
|
||||
activity.getWindowConfiguration().getRotation());
|
||||
}
|
||||
|
||||
ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
|
||||
"Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity);
|
||||
activity.mTaskSupervisor.mStoppingActivities.remove(activity);
|
||||
activity.getDisplayContent().ensureActivitiesVisible(null /* starting */,
|
||||
0 /* configChanges */, false /* preserveWindows */, true);
|
||||
}
|
||||
|
||||
private static void restoreLaunchBehind(@NonNull ActivityRecord activity) {
|
||||
activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
|
||||
|
||||
// Restore the launch-behind state.
|
||||
activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
|
||||
activity.mLaunchTaskBehind = false;
|
||||
ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
|
||||
"Setting Activity.mLauncherTaskBehind to false. Activity=%s",
|
||||
activity);
|
||||
}
|
||||
|
||||
void checkAnimationReady(WallpaperController wallpaperController) {
|
||||
if (!mBackAnimationInProgress) {
|
||||
return;
|
||||
@@ -1039,6 +1104,7 @@ class BackNavigationController {
|
||||
mNavigationMonitor.stopMonitor();
|
||||
mBackAnimationInProgress = false;
|
||||
mShowWallpaper = false;
|
||||
mPendingAnimationBuilder = null;
|
||||
}
|
||||
|
||||
private static TaskSnapshot getActivitySnapshot(@NonNull ActivityRecord r) {
|
||||
|
||||
@@ -989,6 +989,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
cleanUpInternal();
|
||||
mController.updateAnimatingState(mTmpTransaction);
|
||||
mTmpTransaction.apply();
|
||||
|
||||
// Handle back animation if it's already started.
|
||||
mController.mAtm.mBackNavigationController.handleDeferredBackAnimation(mTargets);
|
||||
}
|
||||
|
||||
void abort() {
|
||||
|
||||
Reference in New Issue
Block a user