Merge "Cancel the recents animation when keyguard is occluding.[1/2]" into tm-qpr-dev

This commit is contained in:
Wei Sheng Shih
2022-05-30 01:48:07 +00:00
committed by Android (Google) Code Review
6 changed files with 105 additions and 10 deletions

View File

@@ -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;
@@ -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());
}
@@ -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.");
@@ -241,6 +244,7 @@ public class RemoteTransitionCompat implements Parcelable {
mRecentsTask = recentsTask;
mLeashMap = leashMap;
mTransition = transition;
mKeyguardLocked = keyguardLocked;
}
@SuppressLint("NewApi")
@@ -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
@@ -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 {

View File

@@ -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
@@ -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.
newTransition.abort();
newTransition = null;
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.
@@ -2383,6 +2403,7 @@ class ActivityStarter {
mAvoidMoveToFront = false;
mFrozeTaskList = false;
mTransientLaunch = false;
mDisplayLockAndOccluded = false;
mVoiceSession = null;
mVoiceInteractor = null;
@@ -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) {

View File

@@ -1559,8 +1559,11 @@ class TaskFragment extends WindowContainer<WindowContainer> {
} else {
prev.schedulePauseTimeout();
// Unset readiness since we now need to wait until this pause is complete.
mTransitionController.setReady(this, false /* ready */);
// 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;
}

View File

@@ -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);
}
@@ -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;
@@ -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 {}
@@ -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();
@@ -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;

View File

@@ -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.

View File

@@ -188,7 +188,8 @@ class WallpaperController {
&& animatingContainer.getAnimation().getShowWallpaper();
final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;
final boolean isRecentsTransitionTarget = (recentsAnimationController != null
&& recentsAnimationController.isWallpaperVisible(w));
&& recentsAnimationController.isWallpaperVisible(w))
|| w.mTransitionController.isTransientHide(w.getTask());
if (isRecentsTransitionTarget) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);
mFindResults.setWallpaperTarget(w);