Loading packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +11 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; Loading Loading @@ -168,7 +169,8 @@ public class RemoteTransitionCompat implements Parcelable { } t.apply(); mRecentsSession.setup(controller, info, finishedCallback, pausingTasks, pipTask, recentsTask, leashMap, mToken); recentsTask, leashMap, mToken, (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0); recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0), new Rect()); } Loading Loading @@ -223,12 +225,13 @@ public class RemoteTransitionCompat implements Parcelable { private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null; private PictureInPictureSurfaceTransaction mPipTransaction = null; private IBinder mTransition = null; private boolean mKeyguardLocked = false; void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info, IRemoteTransitionFinishedCallback finishCB, ArrayList<WindowContainerToken> pausingTasks, WindowContainerToken pipTask, WindowContainerToken recentsTask, ArrayMap<SurfaceControl, SurfaceControl> leashMap, IBinder transition) { IBinder transition, boolean keyguardLocked) { if (mInfo != null) { throw new IllegalStateException("Trying to run a new recents animation while" + " recents is already active."); Loading @@ -241,6 +244,7 @@ public class RemoteTransitionCompat implements Parcelable { mRecentsTask = recentsTask; mLeashMap = leashMap; mTransition = transition; mKeyguardLocked = keyguardLocked; } @SuppressLint("NewApi") Loading Loading @@ -375,6 +379,10 @@ public class RemoteTransitionCompat implements Parcelable { final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); final WindowContainerTransaction wct = new WindowContainerTransaction(); if (mKeyguardLocked && mRecentsTask != null) { if (toHome) wct.reorder(mRecentsTask, true /* toTop */); else wct.restoreTransientOrder(mRecentsTask); } if (!toHome && mPausingTasks != null && mOpeningLeashes == null) { // The gesture went back to opening the app rather than continuing with // recents, so end the transition by moving the app back to the top (and also Loading @@ -384,7 +392,7 @@ public class RemoteTransitionCompat implements Parcelable { wct.reorder(mPausingTasks.get(i), true /* onTop */); t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash()); } if (mRecentsTask != null) { if (!mKeyguardLocked && mRecentsTask != null) { wct.restoreTransientOrder(mRecentsTask); } } else { Loading services/core/java/com/android/server/wm/ActivityStarter.java +34 −3 Original line number Diff line number Diff line Loading @@ -211,6 +211,7 @@ class ActivityStarter { // The task which was above the targetTask before starting this activity. null if the targetTask // was already on top or if the activity is in a new task. private Task mPriorAboveTask; private boolean mDisplayLockAndOccluded; // We must track when we deliver the new intent since multiple code paths invoke // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used Loading Loading @@ -1733,19 +1734,38 @@ class ActivityStarter { // Transition housekeeping. final TransitionController transitionController = started.mTransitionController; final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT; final boolean isTransientLaunch = options != null && options.getTransientLaunch(); // Start transient launch while keyguard locked and occluded by other app, for this // condition we would like to play the remote transition without modify any visible state // for the hierarchy in core, so here will force execute this transition. final boolean forceTransientTransition = isTransientLaunch && mPriorAboveTask != null && mDisplayLockAndOccluded; if (isStarted) { // The activity is started new rather than just brought forward, so record it as an // existence change. transitionController.collectExistenceChange(started); } else if (result == START_DELIVERED_TO_TOP && newTransition != null) { // We just delivered to top, so there isn't an actual transition here. if (!forceTransientTransition) { newTransition.abort(); newTransition = null; } if (options != null && options.getTransientLaunch()) { } if (isTransientLaunch) { if (forceTransientTransition && newTransition != null) { newTransition.collect(mLastStartActivityRecord); newTransition.collect(mPriorAboveTask); } // `started` isn't guaranteed to be the actual relevant activity, so we must wait // until after we launched to identify the relevant activity. transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask); if (forceTransientTransition && newTransition != null) { final DisplayContent dc = mLastStartActivityRecord.getDisplayContent(); // update wallpaper target to TransientHide dc.mWallpaperController.adjustWallpaperWindows(); // execute transition because there is no change newTransition.setReady(dc, true /* ready */); } } if (!userLeaving) { // no-user-leaving implies not entering PiP. Loading Loading @@ -2383,6 +2403,7 @@ class ActivityStarter { mAvoidMoveToFront = false; mFrozeTaskList = false; mTransientLaunch = false; mDisplayLockAndOccluded = false; mVoiceSession = null; mVoiceInteractor = null; Loading Loading @@ -2491,6 +2512,16 @@ class ActivityStarter { mAvoidMoveToFront = true; } mTransientLaunch = mOptions.getTransientLaunch(); final KeyguardController kc = mSupervisor.getKeyguardController(); final int displayId = mPreferredTaskDisplayArea.getDisplayId(); mDisplayLockAndOccluded = kc.isKeyguardLocked(displayId) && kc.isDisplayOccluded(displayId); // Recents animation on lock screen, do not resume & move launcher to top. if (mTransientLaunch && mDisplayLockAndOccluded && mService.getTransitionController().isShellTransitionsEnabled()) { mDoResume = false; mAvoidMoveToFront = true; } mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); if (inTaskFragment == null) { Loading services/core/java/com/android/server/wm/TaskFragment.java +5 −2 Original line number Diff line number Diff line Loading @@ -1559,8 +1559,11 @@ class TaskFragment extends WindowContainer<WindowContainer> { } else { prev.schedulePauseTimeout(); // All activities will be stopped when sleeping, don't need to wait for pause. if (!uiSleeping) { // Unset readiness since we now need to wait until this pause is complete. mTransitionController.setReady(this, false /* ready */); } return true; } Loading services/core/java/com/android/server/wm/Transition.java +43 −1 Original line number Diff line number Diff line Loading @@ -214,10 +214,26 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mTransientLaunches = new ArrayMap<>(); } mTransientLaunches.put(activity, restoreBelow); setTransientLaunchToChanges(activity); if (restoreBelow != null) { final ChangeInfo info = mChanges.get(restoreBelow); info.mFlags |= ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH; } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Transition %d: Set %s as " + "transient-launch", mSyncId, activity); } boolean isTransientHide(@NonNull Task task) { if (mTransientLaunches == null) return false; for (int i = 0; i < mTransientLaunches.size(); ++i) { if (mTransientLaunches.valueAt(i) == task) { return true; } } return false; } boolean isTransientLaunch(@NonNull ActivityRecord activity) { return mTransientLaunches != null && mTransientLaunches.containsKey(activity); } Loading @@ -242,6 +258,20 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe info.mFlags = info.mFlags | ChangeInfo.FLAG_SEAMLESS_ROTATION; } /** * Only set flag to the parent tasks and activity itself. */ private void setTransientLaunchToChanges(@NonNull WindowContainer wc) { for (WindowContainer curr = wc; curr != null && mChanges.containsKey(curr); curr = curr.getParent()) { if (curr.asTask() == null && curr.asActivityRecord() == null) { return; } final ChangeInfo info = mChanges.get(curr); info.mFlags = info.mFlags | ChangeInfo.FLAG_TRANSIENT_LAUNCH; } } @VisibleForTesting int getSyncId() { return mSyncId; Loading Loading @@ -1546,10 +1576,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * seamless rotation. This is currently only used by DisplayContent during fixed-rotation. */ private static final int FLAG_SEAMLESS_ROTATION = 1; private static final int FLAG_TRANSIENT_LAUNCH = 2; private static final int FLAG_ABOVE_TRANSIENT_LAUNCH = 4; @IntDef(prefix = { "FLAG_" }, value = { FLAG_NONE, FLAG_SEAMLESS_ROTATION FLAG_SEAMLESS_ROTATION, FLAG_TRANSIENT_LAUNCH, FLAG_ABOVE_TRANSIENT_LAUNCH }) @Retention(RetentionPolicy.SOURCE) @interface Flag {} Loading Loading @@ -1586,6 +1620,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } boolean hasChanged(@NonNull WindowContainer newState) { // the task including transient launch must promote to root task if ((mFlags & ChangeInfo.FLAG_TRANSIENT_LAUNCH) != 0 || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) { return true; } // If it's invisible and hasn't changed visibility, always return false since even if // something changed, it wouldn't be a visible change. final boolean currVisible = newState.isVisibleRequested(); Loading @@ -1601,6 +1640,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe @TransitionInfo.TransitionMode int getTransitMode(@NonNull WindowContainer wc) { if ((mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) { return TRANSIT_CLOSE; } final boolean nowVisible = wc.isVisibleRequested(); if (nowVisible == mVisible) { return TRANSIT_CHANGE; Loading services/core/java/com/android/server/wm/TransitionController.java +10 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,16 @@ class TransitionController { return false; } boolean isTransientHide(@NonNull Task task) { if (mCollectingTransition != null && mCollectingTransition.isTransientHide(task)) { return true; } for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) { if (mPlayingTransitions.get(i).isTransientHide(task)) return true; } return false; } /** * @return {@code true} if {@param ar} is part of a transient-launch activity in an active * transition. Loading Loading
packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +11 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; Loading Loading @@ -168,7 +169,8 @@ public class RemoteTransitionCompat implements Parcelable { } t.apply(); mRecentsSession.setup(controller, info, finishedCallback, pausingTasks, pipTask, recentsTask, leashMap, mToken); recentsTask, leashMap, mToken, (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0); recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0), new Rect()); } Loading Loading @@ -223,12 +225,13 @@ public class RemoteTransitionCompat implements Parcelable { private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null; private PictureInPictureSurfaceTransaction mPipTransaction = null; private IBinder mTransition = null; private boolean mKeyguardLocked = false; void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info, IRemoteTransitionFinishedCallback finishCB, ArrayList<WindowContainerToken> pausingTasks, WindowContainerToken pipTask, WindowContainerToken recentsTask, ArrayMap<SurfaceControl, SurfaceControl> leashMap, IBinder transition) { IBinder transition, boolean keyguardLocked) { if (mInfo != null) { throw new IllegalStateException("Trying to run a new recents animation while" + " recents is already active."); Loading @@ -241,6 +244,7 @@ public class RemoteTransitionCompat implements Parcelable { mRecentsTask = recentsTask; mLeashMap = leashMap; mTransition = transition; mKeyguardLocked = keyguardLocked; } @SuppressLint("NewApi") Loading Loading @@ -375,6 +379,10 @@ public class RemoteTransitionCompat implements Parcelable { final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); final WindowContainerTransaction wct = new WindowContainerTransaction(); if (mKeyguardLocked && mRecentsTask != null) { if (toHome) wct.reorder(mRecentsTask, true /* toTop */); else wct.restoreTransientOrder(mRecentsTask); } if (!toHome && mPausingTasks != null && mOpeningLeashes == null) { // The gesture went back to opening the app rather than continuing with // recents, so end the transition by moving the app back to the top (and also Loading @@ -384,7 +392,7 @@ public class RemoteTransitionCompat implements Parcelable { wct.reorder(mPausingTasks.get(i), true /* onTop */); t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash()); } if (mRecentsTask != null) { if (!mKeyguardLocked && mRecentsTask != null) { wct.restoreTransientOrder(mRecentsTask); } } else { Loading
services/core/java/com/android/server/wm/ActivityStarter.java +34 −3 Original line number Diff line number Diff line Loading @@ -211,6 +211,7 @@ class ActivityStarter { // The task which was above the targetTask before starting this activity. null if the targetTask // was already on top or if the activity is in a new task. private Task mPriorAboveTask; private boolean mDisplayLockAndOccluded; // We must track when we deliver the new intent since multiple code paths invoke // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used Loading Loading @@ -1733,19 +1734,38 @@ class ActivityStarter { // Transition housekeeping. final TransitionController transitionController = started.mTransitionController; final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT; final boolean isTransientLaunch = options != null && options.getTransientLaunch(); // Start transient launch while keyguard locked and occluded by other app, for this // condition we would like to play the remote transition without modify any visible state // for the hierarchy in core, so here will force execute this transition. final boolean forceTransientTransition = isTransientLaunch && mPriorAboveTask != null && mDisplayLockAndOccluded; if (isStarted) { // The activity is started new rather than just brought forward, so record it as an // existence change. transitionController.collectExistenceChange(started); } else if (result == START_DELIVERED_TO_TOP && newTransition != null) { // We just delivered to top, so there isn't an actual transition here. if (!forceTransientTransition) { newTransition.abort(); newTransition = null; } if (options != null && options.getTransientLaunch()) { } if (isTransientLaunch) { if (forceTransientTransition && newTransition != null) { newTransition.collect(mLastStartActivityRecord); newTransition.collect(mPriorAboveTask); } // `started` isn't guaranteed to be the actual relevant activity, so we must wait // until after we launched to identify the relevant activity. transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask); if (forceTransientTransition && newTransition != null) { final DisplayContent dc = mLastStartActivityRecord.getDisplayContent(); // update wallpaper target to TransientHide dc.mWallpaperController.adjustWallpaperWindows(); // execute transition because there is no change newTransition.setReady(dc, true /* ready */); } } if (!userLeaving) { // no-user-leaving implies not entering PiP. Loading Loading @@ -2383,6 +2403,7 @@ class ActivityStarter { mAvoidMoveToFront = false; mFrozeTaskList = false; mTransientLaunch = false; mDisplayLockAndOccluded = false; mVoiceSession = null; mVoiceInteractor = null; Loading Loading @@ -2491,6 +2512,16 @@ class ActivityStarter { mAvoidMoveToFront = true; } mTransientLaunch = mOptions.getTransientLaunch(); final KeyguardController kc = mSupervisor.getKeyguardController(); final int displayId = mPreferredTaskDisplayArea.getDisplayId(); mDisplayLockAndOccluded = kc.isKeyguardLocked(displayId) && kc.isDisplayOccluded(displayId); // Recents animation on lock screen, do not resume & move launcher to top. if (mTransientLaunch && mDisplayLockAndOccluded && mService.getTransitionController().isShellTransitionsEnabled()) { mDoResume = false; mAvoidMoveToFront = true; } mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask()); if (inTaskFragment == null) { Loading
services/core/java/com/android/server/wm/TaskFragment.java +5 −2 Original line number Diff line number Diff line Loading @@ -1559,8 +1559,11 @@ class TaskFragment extends WindowContainer<WindowContainer> { } else { prev.schedulePauseTimeout(); // All activities will be stopped when sleeping, don't need to wait for pause. if (!uiSleeping) { // Unset readiness since we now need to wait until this pause is complete. mTransitionController.setReady(this, false /* ready */); } return true; } Loading
services/core/java/com/android/server/wm/Transition.java +43 −1 Original line number Diff line number Diff line Loading @@ -214,10 +214,26 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mTransientLaunches = new ArrayMap<>(); } mTransientLaunches.put(activity, restoreBelow); setTransientLaunchToChanges(activity); if (restoreBelow != null) { final ChangeInfo info = mChanges.get(restoreBelow); info.mFlags |= ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH; } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Transition %d: Set %s as " + "transient-launch", mSyncId, activity); } boolean isTransientHide(@NonNull Task task) { if (mTransientLaunches == null) return false; for (int i = 0; i < mTransientLaunches.size(); ++i) { if (mTransientLaunches.valueAt(i) == task) { return true; } } return false; } boolean isTransientLaunch(@NonNull ActivityRecord activity) { return mTransientLaunches != null && mTransientLaunches.containsKey(activity); } Loading @@ -242,6 +258,20 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe info.mFlags = info.mFlags | ChangeInfo.FLAG_SEAMLESS_ROTATION; } /** * Only set flag to the parent tasks and activity itself. */ private void setTransientLaunchToChanges(@NonNull WindowContainer wc) { for (WindowContainer curr = wc; curr != null && mChanges.containsKey(curr); curr = curr.getParent()) { if (curr.asTask() == null && curr.asActivityRecord() == null) { return; } final ChangeInfo info = mChanges.get(curr); info.mFlags = info.mFlags | ChangeInfo.FLAG_TRANSIENT_LAUNCH; } } @VisibleForTesting int getSyncId() { return mSyncId; Loading Loading @@ -1546,10 +1576,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * seamless rotation. This is currently only used by DisplayContent during fixed-rotation. */ private static final int FLAG_SEAMLESS_ROTATION = 1; private static final int FLAG_TRANSIENT_LAUNCH = 2; private static final int FLAG_ABOVE_TRANSIENT_LAUNCH = 4; @IntDef(prefix = { "FLAG_" }, value = { FLAG_NONE, FLAG_SEAMLESS_ROTATION FLAG_SEAMLESS_ROTATION, FLAG_TRANSIENT_LAUNCH, FLAG_ABOVE_TRANSIENT_LAUNCH }) @Retention(RetentionPolicy.SOURCE) @interface Flag {} Loading Loading @@ -1586,6 +1620,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } boolean hasChanged(@NonNull WindowContainer newState) { // the task including transient launch must promote to root task if ((mFlags & ChangeInfo.FLAG_TRANSIENT_LAUNCH) != 0 || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) { return true; } // If it's invisible and hasn't changed visibility, always return false since even if // something changed, it wouldn't be a visible change. final boolean currVisible = newState.isVisibleRequested(); Loading @@ -1601,6 +1640,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe @TransitionInfo.TransitionMode int getTransitMode(@NonNull WindowContainer wc) { if ((mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) { return TRANSIT_CLOSE; } final boolean nowVisible = wc.isVisibleRequested(); if (nowVisible == mVisible) { return TRANSIT_CHANGE; Loading
services/core/java/com/android/server/wm/TransitionController.java +10 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,16 @@ class TransitionController { return false; } boolean isTransientHide(@NonNull Task task) { if (mCollectingTransition != null && mCollectingTransition.isTransientHide(task)) { return true; } for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) { if (mPlayingTransitions.get(i).isTransientHide(task)) return true; } return false; } /** * @return {@code true} if {@param ar} is part of a transient-launch activity in an active * transition. Loading