Relocate transition collection around lifecycle events (1/N)
Previously was just using whatever the legacy transition system
used. However, that system would wait too late (until after
round-trips to the client) in order to prepare some transitions.
Since the new transitions utilize "snapshots", they need to
collect earlier in the lifecycle to work properly.
This first CL deals mostly with activity start/finish and
task to-front/to-back. It also adds some utilities like the
ability to abort a transition (needed because activitystarter
works this way) and the ability to un-ready a transition/
sync transaction to enable trampolines.
This also switches the transit types to the new constants.
Bug: 169035022
Test: Existing tests (TransitionTests) pass
Change-Id: I05f3a2e8e27ccaed7077d648daf033aeabc333f9
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 50174df..0eef847 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -170,14 +170,14 @@
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 @@
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 @@
@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 e51bf5e4..f4ccecc 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 04be3b7..388eb28 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 @@
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 1076906..80d1f11 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 @@
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 e2a7afb..019f650 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.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 @@
mUserLeaving = true;
}
+ mService.getTransitionController().requestTransitionIfNeeded(TRANSIT_TO_FRONT, task);
reason = reason + " findTaskToMoveToFront";
boolean reparented = false;
if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
@@ -1516,6 +1519,7 @@
// 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 6f97936..6a320f7 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.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 @@
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 @@
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 @@
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 12c2c0e..e146ada 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 @@
*/
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 @@
}
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 301783c..faeb4ba 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 @@
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 @@
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 @@
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 07c61d3..d7df5cc 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 @@
}
}
+ /**
+ * 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 9068bb7..903e9226 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 @@
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 3200bbc..075dc7d 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 @@
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 ac9c289..c490273 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 @@
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 @@
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 @@
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 @@
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 d5322ea..ecf2cdf 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_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.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 @@
*/
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 @@
*
* 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 @@
}
}
+ 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;
}
+ 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);
- int displayId = DEFAULT_DISPLAY;
- for (WindowContainer container : mParticipants.keySet()) {
- displayId = container.mDisplayContent.getDisplayId();
- }
-
handleNonAppWindowsInTransition(displayId, mType, mFlags);
if (mController.getTransitionPlayer() != null) {
@@ -176,13 +219,14 @@
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 @@
}
}
}
- 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 @@
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 c2fb4cd..773bcaf 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.common.ProtoLog;
import java.util.ArrayList;
-import java.util.Arrays;
/**
* Handles all the aspects of recording and synchronizing transitions.
@@ -44,13 +35,6 @@
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 @@
@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 @@
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 @@
}
/**
- * 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;
}
- final Transition transition = createTransition(type, flags);
+ Transition newTransition = null;
+ if (isCollecting()) {
+ // Make the collecting transition wait until this request is ready.
+ mCollectingTransition.setReady(false);
+ } else {
+ newTransition = requestStartTransition(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 @@
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 @@
}
/** @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 @@
mPlayingTransitions.add(transition);
}
+ void abort(Transition transition) {
+ if (transition != mCollectingTransition) {
+ throw new IllegalStateException("Too late to abort.");
+ }
+ transition.abort();
+ mCollectingTransition = null;
+ }
+
}