summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/TransitionInfo.java14
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/Transitions.java11
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java1
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java23
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java6
-rw-r--r--services/core/java/com/android/server/wm/BLASTSyncEngine.java22
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java22
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java2
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java3
-rw-r--r--services/core/java/com/android/server/wm/Task.java17
-rw-r--r--services/core/java/com/android/server/wm/Transition.java87
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java117
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;
+ }
+
}