Loading core/java/android/window/flags/windowing_frontend.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -340,3 +340,11 @@ flag { is_fixed_read_only: true bug: "362938401" } flag { name: "unify_back_navigation_transition" namespace: "windowing_frontend" description: "Always create predictive back transition when start back gesture animation" bug: "372230928" is_fixed_read_only: true } libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +19 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.wm.shell.back; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION; import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; Loading Loading @@ -1262,6 +1263,15 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return handleCloseTransition(info, st, ft, finishCallback); } @Override public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted, @Nullable SurfaceControl.Transaction finishTransaction) { if (transition == mClosePrepareTransition && aborted) { mClosePrepareTransition = null; applyFinishOpenTransition(); } } void createClosePrepareTransition() { if (mClosePrepareTransition != null) { Log.e(TAG, "Re-create close prepare transition"); Loading Loading @@ -1324,8 +1334,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } if (!isOpen) { // Close transition, the transition info should be: // init info(open A & wallpaper) // current info(close B target) // init info(open A & wallpaper) => init info(open A & change B & wallpaper) // current info(close B target) => current info(change A & close B) // remove init info(open/change A target & wallpaper) boolean moveToTop = false; boolean excludeOpenTarget = false; Loading Loading @@ -1515,14 +1525,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return false; } SurfaceControl openingLeash = null; SurfaceControl closingLeash = null; if (mApps != null) { for (int i = mApps.length - 1; i >= 0; --i) { if (mApps[i].mode == MODE_OPENING) { openingLeash = mApps[i].leash; } else if (mApps[i].mode == MODE_CLOSING) { closingLeash = mApps[i].leash; } } } if (openingLeash != null) { if (openingLeash != null && closingLeash != null) { int rootIdx = -1; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change c = info.getChanges().get(i); Loading @@ -1532,6 +1545,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont st.reparent(c.getLeash(), openingLeash); st.setAlpha(c.getLeash(), 1.0f); rootIdx = TransitionUtil.rootIndexFor(c, info); } else if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED) && c.getMode() == TRANSIT_CHANGE) { st.reparent(c.getLeash(), closingLeash); } } // The root leash and the leash of opening target should actually in the same level, Loading services/core/java/com/android/server/wm/BackNavigationController.java +35 −8 Original line number Diff line number Diff line Loading @@ -1726,8 +1726,7 @@ class BackNavigationController { ActivityRecord currentActivity, ArrayList<ActivityRecord> previousActivity, WindowContainer removedWindowContainer) { final ScheduleAnimationBuilder builder = new ScheduleAnimationBuilder(backType, adapter, monitor); final ScheduleAnimationBuilder builder = new ScheduleAnimationBuilder(adapter, monitor); switch (backType) { case BackNavigationInfo.TYPE_RETURN_TO_HOME: return builder Loading @@ -1752,7 +1751,6 @@ class BackNavigationController { } class ScheduleAnimationBuilder { final int mType; final BackAnimationAdapter mBackAnimationAdapter; final NavigationMonitor mNavigationMonitor; WindowContainer mCloseTarget; Loading @@ -1760,9 +1758,8 @@ class BackNavigationController { boolean mIsLaunchBehind; TaskSnapshot mSnapshot; ScheduleAnimationBuilder(int type, BackAnimationAdapter adapter, ScheduleAnimationBuilder(BackAnimationAdapter adapter, NavigationMonitor monitor) { mType = type; mBackAnimationAdapter = adapter; mNavigationMonitor = monitor; } Loading Loading @@ -1793,7 +1790,36 @@ class BackNavigationController { } private Transition prepareTransitionIfNeeded(ActivityRecord[] visibleOpenActivities) { if (mSnapshot == null) { if (Flags.unifyBackNavigationTransition()) { if (mCloseTarget.asWindowState() != null) { return null; } final ArrayList<ActivityRecord> makeVisibles = new ArrayList<>(); for (int i = visibleOpenActivities.length - 1; i >= 0; --i) { final ActivityRecord activity = visibleOpenActivities[i]; if (activity.mLaunchTaskBehind || activity.isVisibleRequested()) { continue; } makeVisibles.add(activity); } final TransitionController tc = visibleOpenActivities[0].mTransitionController; final Transition prepareOpen = tc.createTransition( TRANSIT_PREPARE_BACK_NAVIGATION); tc.collect(mCloseTarget); prepareOpen.setBackGestureAnimation(mCloseTarget, true /* isTop */); for (int i = mOpenTargets.length - 1; i >= 0; --i) { tc.collect(mOpenTargets[i]); prepareOpen.setBackGestureAnimation(mOpenTargets[i], false /* isTop */); } if (!makeVisibles.isEmpty()) { setLaunchBehind(visibleOpenActivities); } tc.requestStartTransition(prepareOpen, null /*startTask */, null /* remoteTransition */, null /* displayChange */); prepareOpen.setReady(makeVisibles.get(0), true); return prepareOpen; } else if (mSnapshot == null) { return setLaunchBehind(visibleOpenActivities); } return null; Loading Loading @@ -1990,6 +2016,7 @@ class BackNavigationController { private static Transition setLaunchBehind(@NonNull ActivityRecord[] activities) { final boolean migrateBackTransition = Flags.migratePredictiveBackTransition(); final boolean unifyBackNavigationTransition = Flags.unifyBackNavigationTransition(); final ArrayList<ActivityRecord> affects = new ArrayList<>(); for (int i = activities.length - 1; i >= 0; --i) { final ActivityRecord activity = activities[i]; Loading @@ -2003,8 +2030,8 @@ class BackNavigationController { } final TransitionController tc = activities[0].mTransitionController; final Transition prepareOpen = migrateBackTransition && !tc.isCollecting() ? tc.createTransition(TRANSIT_PREPARE_BACK_NAVIGATION) : null; final Transition prepareOpen = migrateBackTransition && !unifyBackNavigationTransition && !tc.isCollecting() ? tc.createTransition(TRANSIT_PREPARE_BACK_NAVIGATION) : null; DisplayContent commonDisplay = null; for (int i = affects.size() - 1; i >= 0; --i) { Loading services/core/java/com/android/server/wm/Transition.java +31 −3 Original line number Diff line number Diff line Loading @@ -557,6 +557,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { }); } /** Set a transition to be a back gesture animation. */ void setBackGestureAnimation(@NonNull WindowContainer wc, boolean isTop) { final ChangeInfo info = mChanges.get(wc); if (info == null) return; info.mFlags = info.mFlags | (isTop ? ChangeInfo.FLAG_BACK_GESTURE_ANIMATION : ChangeInfo.FLAG_BELOW_BACK_GESTURE_ANIMATION); } /** Set a transition to be a seamless-rotation. */ void setSeamlessRotation(@NonNull WindowContainer wc) { final ChangeInfo info = mChanges.get(wc); Loading Loading @@ -3405,6 +3413,18 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { /** Whether this change contains config-at-end members. */ private static final int FLAG_CHANGE_CONFIG_AT_END = 0x40; /** * Whether this change is forced participant transition because it is current top target * of predictive back animation. */ private static final int FLAG_BACK_GESTURE_ANIMATION = 0x80; /** * Whether this change is forced participant transition because it is previous target of * predictive back animation */ private static final int FLAG_BELOW_BACK_GESTURE_ANIMATION = 0x100; @IntDef(prefix = { "FLAG_" }, value = { FLAG_NONE, FLAG_SEAMLESS_ROTATION, Loading @@ -3413,7 +3433,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { FLAG_CHANGE_NO_ANIMATION, FLAG_CHANGE_YES_ANIMATION, FLAG_CHANGE_MOVED_TO_TOP, FLAG_CHANGE_CONFIG_AT_END FLAG_CHANGE_CONFIG_AT_END, FLAG_BACK_GESTURE_ANIMATION, FLAG_BELOW_BACK_GESTURE_ANIMATION }) @Retention(RetentionPolicy.SOURCE) @interface Flag {} Loading Loading @@ -3487,7 +3509,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { final boolean currVisible = mContainer.isVisibleRequested(); // the task including transient launch must promote to root task if (currVisible && ((mFlags & ChangeInfo.FLAG_TRANSIENT_LAUNCH) != 0 || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0)) { || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) || (mFlags & ChangeInfo.FLAG_BACK_GESTURE_ANIMATION) != 0 || (mFlags & ChangeInfo.FLAG_BELOW_BACK_GESTURE_ANIMATION) != 0) { return true; } // If it's invisible and hasn't changed visibility, always return false since even if Loading @@ -3509,6 +3533,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { if ((mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) { return mExistenceChanged ? TRANSIT_CLOSE : TRANSIT_TO_BACK; } if ((mFlags & ChangeInfo.FLAG_BELOW_BACK_GESTURE_ANIMATION) != 0) { return TRANSIT_TO_FRONT; } final boolean nowVisible = wc.isVisibleRequested(); if (nowVisible == mVisible) { return TRANSIT_CHANGE; Loading Loading @@ -3540,7 +3567,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { && topActivity.mStartingData.hasImeSurface()) { flags |= FLAG_WILL_IME_SHOWN; } if (topActivity.mLaunchTaskBehind) { if (topActivity.mLaunchTaskBehind && !topActivity.isAnimating(PARENTS, ANIMATION_TYPE_PREDICT_BACK)) { Slog.e(TAG, "Unexpected launch-task-behind operation in shell transition"); flags |= FLAG_TASK_LAUNCHING_BEHIND; } Loading Loading
core/java/android/window/flags/windowing_frontend.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -340,3 +340,11 @@ flag { is_fixed_read_only: true bug: "362938401" } flag { name: "unify_back_navigation_transition" namespace: "windowing_frontend" description: "Always create predictive back transition when start back gesture animation" bug: "372230928" is_fixed_read_only: true }
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +19 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.wm.shell.back; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION; import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; Loading Loading @@ -1262,6 +1263,15 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return handleCloseTransition(info, st, ft, finishCallback); } @Override public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted, @Nullable SurfaceControl.Transaction finishTransaction) { if (transition == mClosePrepareTransition && aborted) { mClosePrepareTransition = null; applyFinishOpenTransition(); } } void createClosePrepareTransition() { if (mClosePrepareTransition != null) { Log.e(TAG, "Re-create close prepare transition"); Loading Loading @@ -1324,8 +1334,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } if (!isOpen) { // Close transition, the transition info should be: // init info(open A & wallpaper) // current info(close B target) // init info(open A & wallpaper) => init info(open A & change B & wallpaper) // current info(close B target) => current info(change A & close B) // remove init info(open/change A target & wallpaper) boolean moveToTop = false; boolean excludeOpenTarget = false; Loading Loading @@ -1515,14 +1525,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return false; } SurfaceControl openingLeash = null; SurfaceControl closingLeash = null; if (mApps != null) { for (int i = mApps.length - 1; i >= 0; --i) { if (mApps[i].mode == MODE_OPENING) { openingLeash = mApps[i].leash; } else if (mApps[i].mode == MODE_CLOSING) { closingLeash = mApps[i].leash; } } } if (openingLeash != null) { if (openingLeash != null && closingLeash != null) { int rootIdx = -1; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change c = info.getChanges().get(i); Loading @@ -1532,6 +1545,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont st.reparent(c.getLeash(), openingLeash); st.setAlpha(c.getLeash(), 1.0f); rootIdx = TransitionUtil.rootIndexFor(c, info); } else if (c.hasFlags(FLAG_BACK_GESTURE_ANIMATED) && c.getMode() == TRANSIT_CHANGE) { st.reparent(c.getLeash(), closingLeash); } } // The root leash and the leash of opening target should actually in the same level, Loading
services/core/java/com/android/server/wm/BackNavigationController.java +35 −8 Original line number Diff line number Diff line Loading @@ -1726,8 +1726,7 @@ class BackNavigationController { ActivityRecord currentActivity, ArrayList<ActivityRecord> previousActivity, WindowContainer removedWindowContainer) { final ScheduleAnimationBuilder builder = new ScheduleAnimationBuilder(backType, adapter, monitor); final ScheduleAnimationBuilder builder = new ScheduleAnimationBuilder(adapter, monitor); switch (backType) { case BackNavigationInfo.TYPE_RETURN_TO_HOME: return builder Loading @@ -1752,7 +1751,6 @@ class BackNavigationController { } class ScheduleAnimationBuilder { final int mType; final BackAnimationAdapter mBackAnimationAdapter; final NavigationMonitor mNavigationMonitor; WindowContainer mCloseTarget; Loading @@ -1760,9 +1758,8 @@ class BackNavigationController { boolean mIsLaunchBehind; TaskSnapshot mSnapshot; ScheduleAnimationBuilder(int type, BackAnimationAdapter adapter, ScheduleAnimationBuilder(BackAnimationAdapter adapter, NavigationMonitor monitor) { mType = type; mBackAnimationAdapter = adapter; mNavigationMonitor = monitor; } Loading Loading @@ -1793,7 +1790,36 @@ class BackNavigationController { } private Transition prepareTransitionIfNeeded(ActivityRecord[] visibleOpenActivities) { if (mSnapshot == null) { if (Flags.unifyBackNavigationTransition()) { if (mCloseTarget.asWindowState() != null) { return null; } final ArrayList<ActivityRecord> makeVisibles = new ArrayList<>(); for (int i = visibleOpenActivities.length - 1; i >= 0; --i) { final ActivityRecord activity = visibleOpenActivities[i]; if (activity.mLaunchTaskBehind || activity.isVisibleRequested()) { continue; } makeVisibles.add(activity); } final TransitionController tc = visibleOpenActivities[0].mTransitionController; final Transition prepareOpen = tc.createTransition( TRANSIT_PREPARE_BACK_NAVIGATION); tc.collect(mCloseTarget); prepareOpen.setBackGestureAnimation(mCloseTarget, true /* isTop */); for (int i = mOpenTargets.length - 1; i >= 0; --i) { tc.collect(mOpenTargets[i]); prepareOpen.setBackGestureAnimation(mOpenTargets[i], false /* isTop */); } if (!makeVisibles.isEmpty()) { setLaunchBehind(visibleOpenActivities); } tc.requestStartTransition(prepareOpen, null /*startTask */, null /* remoteTransition */, null /* displayChange */); prepareOpen.setReady(makeVisibles.get(0), true); return prepareOpen; } else if (mSnapshot == null) { return setLaunchBehind(visibleOpenActivities); } return null; Loading Loading @@ -1990,6 +2016,7 @@ class BackNavigationController { private static Transition setLaunchBehind(@NonNull ActivityRecord[] activities) { final boolean migrateBackTransition = Flags.migratePredictiveBackTransition(); final boolean unifyBackNavigationTransition = Flags.unifyBackNavigationTransition(); final ArrayList<ActivityRecord> affects = new ArrayList<>(); for (int i = activities.length - 1; i >= 0; --i) { final ActivityRecord activity = activities[i]; Loading @@ -2003,8 +2030,8 @@ class BackNavigationController { } final TransitionController tc = activities[0].mTransitionController; final Transition prepareOpen = migrateBackTransition && !tc.isCollecting() ? tc.createTransition(TRANSIT_PREPARE_BACK_NAVIGATION) : null; final Transition prepareOpen = migrateBackTransition && !unifyBackNavigationTransition && !tc.isCollecting() ? tc.createTransition(TRANSIT_PREPARE_BACK_NAVIGATION) : null; DisplayContent commonDisplay = null; for (int i = affects.size() - 1; i >= 0; --i) { Loading
services/core/java/com/android/server/wm/Transition.java +31 −3 Original line number Diff line number Diff line Loading @@ -557,6 +557,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { }); } /** Set a transition to be a back gesture animation. */ void setBackGestureAnimation(@NonNull WindowContainer wc, boolean isTop) { final ChangeInfo info = mChanges.get(wc); if (info == null) return; info.mFlags = info.mFlags | (isTop ? ChangeInfo.FLAG_BACK_GESTURE_ANIMATION : ChangeInfo.FLAG_BELOW_BACK_GESTURE_ANIMATION); } /** Set a transition to be a seamless-rotation. */ void setSeamlessRotation(@NonNull WindowContainer wc) { final ChangeInfo info = mChanges.get(wc); Loading Loading @@ -3405,6 +3413,18 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { /** Whether this change contains config-at-end members. */ private static final int FLAG_CHANGE_CONFIG_AT_END = 0x40; /** * Whether this change is forced participant transition because it is current top target * of predictive back animation. */ private static final int FLAG_BACK_GESTURE_ANIMATION = 0x80; /** * Whether this change is forced participant transition because it is previous target of * predictive back animation */ private static final int FLAG_BELOW_BACK_GESTURE_ANIMATION = 0x100; @IntDef(prefix = { "FLAG_" }, value = { FLAG_NONE, FLAG_SEAMLESS_ROTATION, Loading @@ -3413,7 +3433,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { FLAG_CHANGE_NO_ANIMATION, FLAG_CHANGE_YES_ANIMATION, FLAG_CHANGE_MOVED_TO_TOP, FLAG_CHANGE_CONFIG_AT_END FLAG_CHANGE_CONFIG_AT_END, FLAG_BACK_GESTURE_ANIMATION, FLAG_BELOW_BACK_GESTURE_ANIMATION }) @Retention(RetentionPolicy.SOURCE) @interface Flag {} Loading Loading @@ -3487,7 +3509,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { final boolean currVisible = mContainer.isVisibleRequested(); // the task including transient launch must promote to root task if (currVisible && ((mFlags & ChangeInfo.FLAG_TRANSIENT_LAUNCH) != 0 || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0)) { || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) || (mFlags & ChangeInfo.FLAG_BACK_GESTURE_ANIMATION) != 0 || (mFlags & ChangeInfo.FLAG_BELOW_BACK_GESTURE_ANIMATION) != 0) { return true; } // If it's invisible and hasn't changed visibility, always return false since even if Loading @@ -3509,6 +3533,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { if ((mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) { return mExistenceChanged ? TRANSIT_CLOSE : TRANSIT_TO_BACK; } if ((mFlags & ChangeInfo.FLAG_BELOW_BACK_GESTURE_ANIMATION) != 0) { return TRANSIT_TO_FRONT; } final boolean nowVisible = wc.isVisibleRequested(); if (nowVisible == mVisible) { return TRANSIT_CHANGE; Loading Loading @@ -3540,7 +3567,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { && topActivity.mStartingData.hasImeSurface()) { flags |= FLAG_WILL_IME_SHOWN; } if (topActivity.mLaunchTaskBehind) { if (topActivity.mLaunchTaskBehind && !topActivity.isAnimating(PARENTS, ANIMATION_TYPE_PREDICT_BACK)) { Slog.e(TAG, "Unexpected launch-task-behind operation in shell transition"); flags |= FLAG_TASK_LAUNCHING_BEHIND; } Loading