diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index a27f3e49457dc..19a12f2b9cc04 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1468,9 +1468,8 @@ class ActivityStarter { // transition based on a sub-action. // Only do the create here (and defer requestStart) since startActivityInner might abort. final TransitionController transitionController = r.mTransitionController; - Transition newTransition = (!transitionController.isCollecting() - && transitionController.getTransitionPlayer() != null) - ? transitionController.createTransition(TRANSIT_OPEN) : null; + Transition newTransition = transitionController.isShellTransitionsEnabled() + ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null; RemoteTransition remoteTransition = r.takeRemoteTransition(); try { mService.deferWindowLayout(); diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index e1da91a6cb21e..7cb6b46666f91 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -874,7 +874,7 @@ class TransitionController { tryStartCollectFromQueue(); } - private boolean canStartCollectingNow(Transition queued) { + private boolean canStartCollectingNow(@Nullable Transition queued) { if (mCollectingTransition == null) return true; // Population (collect until ready) is still serialized, so always wait for that. if (!mCollectingTransition.isPopulated()) return false; @@ -947,14 +947,14 @@ class TransitionController { * `collecting` transition. It may still ultimately block in sync-engine or become dependent * in {@link #getIsIndependent} later. */ - boolean getCanBeIndependent(Transition collecting, Transition queued) { + boolean getCanBeIndependent(Transition collecting, @Nullable Transition queued) { // For tests - if (queued.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL + if (queued != null && queued.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL && collecting.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL) { return true; } // For recents - if (queued.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) { + if (queued != null && queued.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) { if (collecting.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) { // Must serialize with itself. return false; @@ -1251,6 +1251,44 @@ class TransitionController { return true; } + /** + * This will create and start collecting for a transition if possible. If there's no way to + * start collecting for `parallelType` now, then this returns null. + * + * WARNING: ONLY use this if the transition absolutely cannot be deferred! + */ + @NonNull + Transition createAndStartCollecting(int type) { + if (mTransitionPlayer == null) { + return null; + } + if (!mQueuedTransitions.isEmpty()) { + // There is a queue, so it's not possible to start immediately + return null; + } + if (mSyncEngine.hasActiveSync()) { + if (isCollecting()) { + // Check if we can run in parallel here. + if (canStartCollectingNow(null /* transit */)) { + // create and collect in parallel. + ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS_MIN, "Moving #%d from" + + " collecting to waiting.", mCollectingTransition.getSyncId()); + mWaitingTransitions.add(mCollectingTransition); + mCollectingTransition = null; + Transition transit = new Transition(type, 0 /* flags */, this, mSyncEngine); + moveToCollecting(transit); + return transit; + } + } else { + Slog.w(TAG, "Ongoing Sync outside of transition."); + } + return null; + } + Transition transit = new Transition(type, 0 /* flags */, this, mSyncEngine); + moveToCollecting(transit); + return transit; + } + /** Returns {@code true} if it started collecting, {@code false} if it was queued. */ boolean startLegacySyncOrQueue(BLASTSyncEngine.SyncGroup syncGroup, Runnable applySync) { if (!mQueuedTransitions.isEmpty() || mSyncEngine.hasActiveSync()) {