diff options
14 files changed, 222 insertions, 119 deletions
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 50174dfd8899..0eef84765890 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -170,14 +170,14 @@ public final class TransitionInfo implements Parcelable { private final Rect mStartBounds = new Rect(); private final Rect mEndBounds = new Rect(); - public Change(@NonNull WindowContainerToken container, @NonNull SurfaceControl leash) { + public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) { mContainer = container; mLeash = leash; } private Change(Parcel in) { - mContainer = WindowContainerToken.CREATOR.createFromParcel(in); - mParent = in.readParcelable(WindowContainerToken.class.getClassLoader()); + mContainer = in.readTypedObject(WindowContainerToken.CREATOR); + mParent = in.readTypedObject(WindowContainerToken.CREATOR); mLeash = new SurfaceControl(); mLeash.readFromParcel(in); mMode = in.readInt(); @@ -205,8 +205,8 @@ public final class TransitionInfo implements Parcelable { mEndBounds.set(rect); } - /** @return the container that is changing */ - @NonNull + /** @return the container that is changing. May be null if non-remotable (eg. activity) */ + @Nullable public WindowContainerToken getContainer() { return mContainer; } @@ -252,8 +252,8 @@ public final class TransitionInfo implements Parcelable { @Override /** @hide */ public void writeToParcel(@NonNull Parcel dest, int flags) { - mContainer.writeToParcel(dest, flags); - dest.writeParcelable(mParent, 0); + dest.writeTypedObject(mContainer, flags); + dest.writeTypedObject(mParent, flags); mLeash.writeToParcel(dest, flags); dest.writeInt(mMode); mStartBounds.writeToParcel(dest, flags); diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index e51bf5e4e1f6..f4ccecc7e62f 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -1027,6 +1027,12 @@ "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java" }, + "-874888131": { + "message": "Set transition ready=%b %d", + "level": "VERBOSE", + "group": "WM_DEBUG_WINDOW_TRANSITIONS", + "at": "com\/android\/server\/wm\/Transition.java" + }, "-874446906": { "message": "showBootMessage: msg=%s always=%b mAllowBootMessages=%b mShowingBootMessages=%b mSystemBooted=%b. %s", "level": "INFO", @@ -2509,12 +2515,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowToken.java" }, - "849147756": { - "message": "Finish collecting in transition %d", - "level": "VERBOSE", - "group": "WM_DEBUG_WINDOW_TRANSITIONS", - "at": "com\/android\/server\/wm\/Transition.java" - }, "853091290": { "message": "Moved stack=%s behind stack=%s", "level": "DEBUG", diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java index 04be3b70fc65..388eb28223dc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java @@ -109,13 +109,10 @@ public class Transitions extends ITransitionPlayer.Stub { mAnimExecutor.execute(va::start); } - private static boolean isOpeningType(@WindowManager.TransitionOldType int legacyType) { - // TODO(shell-transitions): consider providing and using z-order vs the global type for - // this determination. - return legacyType == WindowManager.TRANSIT_OLD_TASK_OPEN - || legacyType == WindowManager.TRANSIT_OLD_TASK_TO_FRONT - || legacyType == WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND - || legacyType == WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; + private static boolean isOpeningType(@WindowManager.TransitionType int type) { + return type == WindowManager.TRANSIT_OPEN + || type == WindowManager.TRANSIT_TO_FRONT + || type == WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; } @Override diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 107690614f82..80d1f1148cb6 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2983,6 +2983,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (stopped) { clearOptionsLocked(); } + mAtmService.getTransitionController().requestTransitionIfNeeded(TRANSIT_CLOSE, this); } /** diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index e2a7afb64fca..019f650c5f1c 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -43,6 +43,8 @@ import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.TRANSIT_CLOSE; +import static android.view.WindowManager.TRANSIT_TO_FRONT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; @@ -1349,6 +1351,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mUserLeaving = true; } + mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_TO_FRONT, task); reason = reason + " findTaskToMoveToFront"; boolean reparented = false; if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) { @@ -1516,6 +1519,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // Prevent recursion. return; } + mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_CLOSE, task); task.mInRemoveTask = true; try { task.performClearTask(reason); diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 6f979363e3bd..6a320f7b1e6d 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -55,6 +55,7 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.INVALID_UID; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.TRANSIT_OPEN; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; @@ -1566,6 +1567,15 @@ class ActivityStarter { boolean restrictedBgActivity, NeededUriGrants intentGrants) { int result = START_CANCELED; final Task startedActivityStack; + + // Create a transition now to record the original intent of actions taken within + // startActivityInner. Otherwise, logic in startActivityInner could start a different + // transition based on a sub-action. + // Only do the create here (and defer requestStart) since startActivityInner might abort. + final Transition newTransition = (!mService.getTransitionController().isCollecting() + && mService.getTransitionController().getTransitionPlayer() != null) + ? mService.getTransitionController().createTransition(TRANSIT_OPEN) : null; + mService.getTransitionController().collect(r); try { mService.deferWindowLayout(); Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner"); @@ -1575,6 +1585,18 @@ class ActivityStarter { Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); startedActivityStack = handleStartResult(r, result); mService.continueWindowLayout(); + + // Transition housekeeping + if (!ActivityManager.isStartResultSuccessful(result)) { + if (newTransition != null) { + newTransition.abort(); + } + } else if (newTransition != null) { + mService.getTransitionController().requestStartTransition(newTransition); + } else { + // Make the collecting transition wait until this request is ready. + mService.getTransitionController().setReady(false); + } } postStartActivityProcessing(r, result, startedActivityStack); @@ -2607,6 +2629,7 @@ class ActivityStarter { mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession, mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions); + mService.getTransitionController().collect(task); addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask"); ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s", diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 12c2c0e54ce7..e146adadffe7 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -2297,8 +2297,7 @@ public class AppTransition implements Dump { */ boolean prepareAppTransitionOld(@TransitionOldType int transit, boolean alwaysKeepCurrent, @TransitionFlags int flags, boolean forceOverride) { - if (mService.mAtmService.getTransitionController().adaptLegacyPrepare( - transit, flags, forceOverride)) { + if (mService.mAtmService.getTransitionController().getTransitionPlayer() != null) { return false; } ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, @@ -2334,6 +2333,9 @@ public class AppTransition implements Dump { } boolean prepareAppTransition(@TransitionType int transit, @TransitionFlags int flags) { + if (mService.mAtmService.getTransitionController().getTransitionPlayer() != null) { + return false; + } mNextAppTransitionRequests.add(transit); mNextAppTransitionFlags |= flags; updateBooster(); diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java index 301783c155e1..faeb4ba36748 100644 --- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java +++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java @@ -100,6 +100,10 @@ class BLASTSyncEngine { return; } } + finishNow(); + } + + private void finishNow() { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Finished!", mSyncId); SurfaceControl.Transaction merged = mWm.mTransactionFactory.get(); if (mOrphanTransaction != null) { @@ -112,9 +116,10 @@ class BLASTSyncEngine { mActiveSyncs.remove(mSyncId); } - private void setReady() { + private void setReady(boolean ready) { ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Set ready", mSyncId); - mReady = true; + mReady = ready; + if (!ready) return; mWm.mWindowPlacerLocked.requestTraversal(); } @@ -153,8 +158,19 @@ class BLASTSyncEngine { mActiveSyncs.get(id).addToSync(wc); } + void setReady(int id, boolean ready) { + mActiveSyncs.get(id).setReady(ready); + } + void setReady(int id) { - mActiveSyncs.get(id).setReady(); + setReady(id, true); + } + + /** + * Aborts the sync (ie. it doesn't wait for ready or anything to finish) + */ + void abort(int id) { + mActiveSyncs.get(id).finishNow(); } void onSurfacePlacement() { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 07c61d3dcea5..d7df5cc99e69 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -4539,6 +4539,28 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } } + /** + * Helper that both requests a transition (using the new transition system) and prepares + * the legacy transition system. Use this when both systems have the same start-point. + * + * @see TransitionController#requestTransitionIfNeeded(int, int, WindowContainer) + * @see AppTransition#prepareAppTransition + */ + void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit, + @WindowManager.TransitionFlags int flags) { + prepareAppTransition(transit, flags); + mAtmService.getTransitionController().requestTransitionIfNeeded(transit, flags, + null /* trigger */); + } + + /** @see #requestTransitionAndLegacyPrepare(int, int) */ + void requestTransitionAndLegacyPrepare(@WindowManager.TransitionType int transit, + @Nullable WindowContainer trigger) { + prepareAppTransition(transit); + mAtmService.getTransitionController().requestTransitionIfNeeded(transit, 0 /* flags */, + trigger); + } + void executeAppTransition() { mAtmService.getTransitionController().setReady(); if (mAppTransition.isTransitionSet()) { diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java index 9068bb75f405..903e92263fb8 100644 --- a/services/core/java/com/android/server/wm/KeyguardController.java +++ b/services/core/java/com/android/server/wm/KeyguardController.java @@ -215,7 +215,7 @@ class KeyguardController { false /* alwaysKeepCurrent */, convertTransitFlags(flags), false /* forceOverride */); mRootWindowContainer.getDefaultDisplay() - .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, + .requestTransitionAndLegacyPrepare(TRANSIT_KEYGUARD_GOING_AWAY, convertTransitFlags(flags)); updateKeyguardSleepToken(); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 3200bbc90de1..075dc7dd6836 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2802,7 +2802,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> r.detachFromProcess(); r.mDisplayContent.prepareAppTransitionOld(TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */); - r.mDisplayContent.prepareAppTransition(TRANSIT_CLOSE, TRANSIT_FLAG_APP_CRASHED); + r.mDisplayContent.requestTransitionAndLegacyPrepare(TRANSIT_CLOSE, + TRANSIT_FLAG_APP_CRASHED); r.destroyIfPossible("handleAppCrashed"); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index ac9c28935211..c490273f9180 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -6417,6 +6417,7 @@ class Task extends WindowContainer<WindowContainer> { final DisplayContent dc = mDisplayContent; if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: starting " + r); + // TODO(shell-transitions): record NO_ANIMATION flag somewhere. if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { dc.prepareAppTransitionOld(TRANSIT_OLD_NONE, keepCurTransition); dc.prepareAppTransition(TRANSIT_NONE); @@ -6438,16 +6439,8 @@ class Task extends WindowContainer<WindowContainer> { transit = TRANSIT_OLD_TASK_OPEN; } } - if (mAtmService.getTransitionController().isShellTransitionsEnabled() - // TODO(shell-transitions): eventually all transitions. - && transit == TRANSIT_OLD_TASK_OPEN) { - Transition transition = - mAtmService.getTransitionController().requestTransition(transit); - transition.collect(task); - } else { - dc.prepareAppTransitionOld(transit, keepCurTransition); - dc.prepareAppTransition(TRANSIT_OPEN); - } + dc.prepareAppTransitionOld(transit, keepCurTransition); + dc.prepareAppTransition(TRANSIT_OPEN); mStackSupervisor.mNoAnimActivities.remove(r); } boolean doShow = true; @@ -6587,7 +6580,7 @@ class Task extends WindowContainer<WindowContainer> { Task finishedTask = r.getTask(); mDisplayContent.prepareAppTransitionOld( TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */); - mDisplayContent.prepareAppTransition(TRANSIT_CLOSE, TRANSIT_FLAG_APP_CRASHED); + mDisplayContent.requestTransitionAndLegacyPrepare(TRANSIT_CLOSE, TRANSIT_FLAG_APP_CRASHED); r.finishIfPossible(reason, false /* oomAdj */); // Also terminate any activities below it that aren't yet stopped, to avoid a situation @@ -6965,7 +6958,7 @@ class Task extends WindowContainer<WindowContainer> { mDisplayContent.prepareAppTransitionOld(TRANSIT_OLD_TASK_TO_BACK, false /* alwaysKeepCurrent */); - mDisplayContent.prepareAppTransition(TRANSIT_TO_BACK); + mDisplayContent.requestTransitionAndLegacyPrepare(TRANSIT_TO_BACK, tr); moveToBack("moveTaskToBackLocked", tr); if (inPinnedWindowingMode()) { diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index d5322eac3886..ecf2cdfb6b6b 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -22,13 +22,14 @@ import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANI import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; -import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; -import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; +import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; +import android.annotation.IntDef; import android.annotation.NonNull; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.os.SystemClock; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; @@ -41,6 +42,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.common.ProtoLog; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Map; @@ -65,17 +68,32 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe */ private static final int STATE_PLAYING = 2; - final @WindowManager.TransitionOldType int mType; + /** + * This transition is aborting or has aborted. No animation will play nor will anything get + * sent to the player. + */ + private static final int STATE_ABORT = 3; + + @IntDef(prefix = { "STATE_" }, value = { + STATE_COLLECTING, + STATE_STARTED, + STATE_PLAYING, + STATE_ABORT + }) + @Retention(RetentionPolicy.SOURCE) + @interface TransitionState {} + + final @WindowManager.TransitionType int mType; private int mSyncId; private @WindowManager.TransitionFlags int mFlags; private final TransitionController mController; private final BLASTSyncEngine mSyncEngine; final ArrayMap<WindowContainer, ChangeInfo> mParticipants = new ArrayMap<>(); - private int mState = STATE_COLLECTING; + private @TransitionState int mState = STATE_COLLECTING; private boolean mReadyCalled = false; - Transition(@WindowManager.TransitionOldType int type, - @WindowManager.TransitionFlags int flags, TransitionController controller) { + Transition(@WindowManager.TransitionType int type, @WindowManager.TransitionFlags int flags, + TransitionController controller) { mType = type; mFlags = flags; mController = controller; @@ -116,15 +134,20 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe * * If this is called before the transition is started, it will be deferred until start. */ - void setReady() { + void setReady(boolean ready) { if (mSyncId < 0) return; if (mState < STATE_STARTED) { - mReadyCalled = true; + mReadyCalled = ready; return; } ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, - "Finish collecting in transition %d", mSyncId); - mSyncEngine.setReady(mSyncId); + "Set transition ready=%b %d", ready, mSyncId); + mSyncEngine.setReady(mSyncId, ready); + } + + /** @see #setReady . This calls with parameter true. */ + void setReady() { + setReady(true); } /** The transition has finished animating and is ready to finalize WM state */ @@ -143,21 +166,41 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } } + void abort() { + // This calls back into itself via controller.abort, so just early return here. + if (mState == STATE_ABORT) return; + if (mState != STATE_COLLECTING) { + throw new IllegalStateException("Too late to abort."); + } + mState = STATE_ABORT; + // Syncengine abort will call through to onTransactionReady() + mSyncEngine.abort(mSyncId); + } + @Override public void onTransactionReady(int syncId, SurfaceControl.Transaction transaction) { if (syncId != mSyncId) { Slog.e(TAG, "Unexpected Sync ID " + syncId + ". Expected " + mSyncId); return; } - mState = STATE_PLAYING; - mController.moveToPlaying(this); - final TransitionInfo info = calculateTransitionInfo(mType, mParticipants); - int displayId = DEFAULT_DISPLAY; for (WindowContainer container : mParticipants.keySet()) { + if (container.mDisplayContent == null) continue; displayId = container.mDisplayContent.getDisplayId(); } + if (mState == STATE_ABORT) { + mController.abort(this); + mController.mAtm.mRootWindowContainer.getDisplayContent(displayId) + .getPendingTransaction().merge(transaction); + mSyncId = -1; + return; + } + + mState = STATE_PLAYING; + mController.moveToPlaying(this); + final TransitionInfo info = calculateTransitionInfo(mType, mParticipants); + handleNonAppWindowsInTransition(displayId, mType, mFlags); if (mController.getTransitionPlayer() != null) { @@ -176,13 +219,14 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe mSyncId = -1; } - private void handleNonAppWindowsInTransition(int displayId, int transit, int flags) { + private void handleNonAppWindowsInTransition(int displayId, + @WindowManager.TransitionType int transit, int flags) { final DisplayContent dc = mController.mAtm.mRootWindowContainer.getDisplayContent(displayId); if (dc == null) { return; } - if (transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY) { + if (transit == TRANSIT_KEYGUARD_GOING_AWAY) { if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0 && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0 && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) == 0) { @@ -196,13 +240,13 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } } } - if (transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY - || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER) { + if (transit == TRANSIT_KEYGUARD_GOING_AWAY) { dc.startKeyguardExitOnNonAppWindows( - transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER, + (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0, (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0, (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0); - mController.mAtm.mWindowManager.mPolicy.startKeyguardExitAnimation(transit, 0); + mController.mAtm.mWindowManager.mPolicy.startKeyguardExitAnimation( + SystemClock.uptimeMillis(), 0 /* duration */); } } @@ -447,7 +491,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe final WindowContainer target = targets.keyAt(i); final ChangeInfo info = targets.valueAt(i); final TransitionInfo.Change change = new TransitionInfo.Change( - target.mRemoteToken.toWindowContainerToken(), target.getSurfaceControl()); + target.mRemoteToken != null ? target.mRemoteToken.toWindowContainerToken() + : null, target.getSurfaceControl()); if (info.mParent != null) { change.setParent(info.mParent.mRemoteToken.toWindowContainerToken()); } diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index c2fb4cd9f6b3..773bcaf14f15 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -16,14 +16,6 @@ package com.android.server.wm; -import static android.view.WindowManager.TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; -import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN; -import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND; -import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_BACK; -import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_FRONT; - import android.annotation.NonNull; import android.annotation.Nullable; import android.os.IBinder; @@ -36,7 +28,6 @@ import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.common.ProtoLog; import java.util.ArrayList; -import java.util.Arrays; /** * Handles all the aspects of recording and synchronizing transitions. @@ -44,13 +35,6 @@ import java.util.Arrays; class TransitionController { private static final String TAG = "TransitionController"; - private static final int[] SUPPORTED_LEGACY_TRANSIT_TYPES = {TRANSIT_OLD_TASK_OPEN, - TRANSIT_OLD_TASK_CLOSE, TRANSIT_OLD_TASK_TO_FRONT, TRANSIT_OLD_TASK_TO_BACK, - TRANSIT_OLD_TASK_OPEN_BEHIND, TRANSIT_OLD_KEYGUARD_GOING_AWAY}; - static { - Arrays.sort(SUPPORTED_LEGACY_TRANSIT_TYPES); - } - private ITransitionPlayer mTransitionPlayer; private final IBinder.DeathRecipient mTransitionPlayerDeath = () -> mTransitionPlayer = null; final ActivityTaskManagerService mAtm; @@ -81,6 +65,9 @@ class TransitionController { @NonNull Transition createTransition(@WindowManager.TransitionOldType int type, @WindowManager.TransitionFlags int flags) { + if (mTransitionPlayer == null) { + throw new IllegalStateException("Shell Transitions not enabled"); + } if (mCollectingTransition != null) { throw new IllegalStateException("Simultaneous transitions not supported yet."); } @@ -111,6 +98,14 @@ class TransitionController { return mTransitionPlayer != null; } + /** + * @return {@code true} if transition is actively collecting changes. This is {@code false} + * once a transition is playing + */ + boolean isCollecting() { + return mCollectingTransition != null; + } + /** @return {@code true} if a transition is running */ boolean inTransition() { // TODO(shell-transitions): eventually properly support multiple @@ -133,26 +128,46 @@ class TransitionController { } /** - * Creates a transition and asks the TransitionPlayer (Shell) to start it. - * @return the created transition. Collection can start immediately. + * @see #requestTransitionIfNeeded(int, int) */ - @NonNull - Transition requestTransition(@WindowManager.TransitionOldType int type) { - return requestTransition(type, 0 /* flags */); + @Nullable + Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, + @Nullable WindowContainer trigger) { + return requestTransitionIfNeeded(type, 0 /* flags */, trigger); } - /** @see #requestTransition */ - @NonNull - Transition requestTransition(@WindowManager.TransitionOldType int type, - @WindowManager.TransitionFlags int flags) { + /** + * If a transition isn't requested yet, creates one and asks the TransitionPlayer (Shell) to + * start it. Collection can start immediately. + * @param trigger if non-null, this is the first container that will be collected + * @return the created transition if created or null otherwise. + */ + @Nullable + Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, + @WindowManager.TransitionFlags int flags, @Nullable WindowContainer trigger) { if (mTransitionPlayer == null) { - throw new IllegalStateException("Shell Transitions not enabled"); + return null; + } + Transition newTransition = null; + if (isCollecting()) { + // Make the collecting transition wait until this request is ready. + mCollectingTransition.setReady(false); + } else { + newTransition = requestStartTransition(createTransition(type, flags)); } - final Transition transition = createTransition(type, flags); + if (trigger != null) { + collect(trigger); + } + return newTransition; + } + + /** Asks the transition player (shell) to start a created but not yet started transition. */ + @NonNull + Transition requestStartTransition(@NonNull Transition transition) { try { ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Requesting StartTransition: %s", transition); - mTransitionPlayer.requestStartTransition(type, transition); + mTransitionPlayer.requestStartTransition(transition.mType, transition); } catch (RemoteException e) { Slog.e(TAG, "Error requesting transition", e); transition.start(); @@ -160,35 +175,6 @@ class TransitionController { return transition; } - /** - * Temporary adapter that converts the legacy AppTransition's prepareAppTransition call into - * a Shell transition request. If shell transitions are enabled, this will take priority in - * handling transition types that it supports. All other transitions will be ignored and thus - * be handled by the legacy apptransition system. This allows both worlds to live in tandem - * during migration. - * - * @return {@code true} if the transition is handled. - */ - boolean adaptLegacyPrepare(@WindowManager.TransitionOldType int transit, - @WindowManager.TransitionFlags int flags, boolean forceOverride) { - if (!isShellTransitionsEnabled() - || Arrays.binarySearch(SUPPORTED_LEGACY_TRANSIT_TYPES, transit) < 0) { - return false; - } - if (inTransition()) { - if (AppTransition.isKeyguardTransit(transit)) { - // TODO(shell-transitions): add to flags - } else if (forceOverride) { - // TODO(shell-transitions): sort out these flags - } else if (transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE) { - // TODO(shell-transitions): record crashing - } - } else { - requestTransition(transit, flags); - } - return true; - } - /** @see Transition#collect */ void collect(@NonNull WindowContainer wc) { if (mCollectingTransition == null) return; @@ -196,9 +182,14 @@ class TransitionController { } /** @see Transition#setReady */ - void setReady() { + void setReady(boolean ready) { if (mCollectingTransition == null) return; - mCollectingTransition.setReady(); + mCollectingTransition.setReady(ready); + } + + /** @see Transition#setReady */ + void setReady() { + setReady(true); } /** @see Transition#finishTransition */ @@ -221,4 +212,12 @@ class TransitionController { mPlayingTransitions.add(transition); } + void abort(Transition transition) { + if (transition != mCollectingTransition) { + throw new IllegalStateException("Too late to abort."); + } + transition.abort(); + mCollectingTransition = null; + } + } |