Merge "Revert "Create a type for tracking chains of Actions requested of WM"" into main
diff --git a/services/core/java/com/android/server/wm/ActionChain.java b/services/core/java/com/android/server/wm/ActionChain.java
deleted file mode 100644
index c697d33..0000000
--- a/services/core/java/com/android/server/wm/ActionChain.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.util.Slog;
-
-import com.android.window.flags.Flags;
-
-/**
- * Represents a chain of WM actions where each action is "caused by" the prior action (except the
- * first one of course). A whole chain is associated with one Transition (in fact, the purpose
- * of this object is to communicate, to all callees, which transition they are part of).
- *
- * A single action is defined as "one logical thing requested of WM". This usually corresponds to
- * each ingress-point into the process. For example, when starting an activity:
- * * the first action is to pause the current/top activity.
- * At this point, control leaves the process while the activity pauses.
- * * Then WM receives completePause (a new ingress). This is a new action that gets linked
- * to the prior action. This action involves resuming the next activity, at which point,
- * control leaves the process again.
- * * Eventually, when everything is done, we will have formed a chain of actions.
- *
- * We don't technically need to hold onto each prior action in the chain once a new action has
- * been linked to the same transition; however, keeping the whole chain enables improved
- * debugging and the ability to detect anomalies.
- */
-public class ActionChain {
- private static final String TAG = "TransitionChain";
-
- /**
- * Normal link type. This means the action was expected and is properly linked to the
- * current chain.
- */
- static final int TYPE_NORMAL = 0;
-
- /**
- * This is the "default" link. It means we haven't done anything to properly track this case
- * so it may or may not be correct. It represents the behavior as if there was no tracking.
- *
- * Any type that has "default" behavior uses the global "collecting transition" if it exists,
- * otherwise it doesn't use any transition.
- */
- static final int TYPE_DEFAULT = 1;
-
- /**
- * This means the action was performed via a legacy code-path. These should be removed
- * eventually. This will have the "default" behavior.
- */
- static final int TYPE_LEGACY = 2;
-
- /** This is for a test. */
- static final int TYPE_TEST = 3;
-
- /** This is finishing a transition. Collection isn't supported during this. */
- static final int TYPE_FINISH = 4;
-
- /**
- * Something unexpected happened so this action was started to recover from the unexpected
- * state. This means that a "real" chain-link couldn't be determined. For now, the behavior of
- * this is the same as "default".
- */
- static final int TYPE_FAILSAFE = 5;
-
- /**
- * Types of chain links (ie. how is this action associated with the chain it is linked to).
- * @hide
- */
- @IntDef(prefix = { "TYPE_" }, value = {
- TYPE_NORMAL,
- TYPE_DEFAULT,
- TYPE_LEGACY,
- TYPE_TEST,
- TYPE_FINISH,
- TYPE_FAILSAFE
- })
- public @interface LinkType {}
-
- /** Identifies the entry-point of this action. */
- @NonNull
- final String mSource;
-
- /** Reference to ATMS. TEMPORARY! ONLY USE THIS WHEN tracker_plumbing flag is DISABLED! */
- @Nullable
- ActivityTaskManagerService mTmpAtm;
-
- /** The transition that this chain's changes belong to. */
- @Nullable
- Transition mTransition;
-
- /** The previous action in the chain. */
- @Nullable
- ActionChain mPrevious = null;
-
- /** Classification of how this action is connected to the chain. */
- @LinkType int mType = TYPE_NORMAL;
-
- /** When this Action started. */
- long mCreateTimeMs;
-
- private ActionChain(String source, @LinkType int type, Transition transit) {
- mSource = source;
- mCreateTimeMs = System.currentTimeMillis();
- mType = type;
- mTransition = transit;
- if (mTransition != null) {
- mTransition.recordChain(this);
- }
- }
-
- private Transition getTransition() {
- if (!Flags.transitTrackerPlumbing()) {
- return mTmpAtm.getTransitionController().getCollectingTransition();
- }
- return mTransition;
- }
-
- boolean isFinishing() {
- return mType == TYPE_FINISH;
- }
-
- /**
- * Some common checks to determine (and report) whether this chain has a collecting transition.
- */
- private boolean expectCollecting() {
- if (getTransition() == null) {
- Slog.e(TAG, "Can't collect into a chain with no transition");
- return false;
- }
- if (isFinishing()) {
- Slog.e(TAG, "Trying to collect into a finished transition");
- return false;
- }
- if (mTransition.mController.getCollectingTransition() != mTransition) {
- Slog.e(TAG, "Mismatch between current collecting ("
- + mTransition.mController.getCollectingTransition() + ") and chain ("
- + mTransition + ")");
- return false;
- }
- return true;
- }
-
- /**
- * Helper to collect a container into the associated transition. This will automatically do
- * nothing if the chain isn't associated with a collecting transition.
- */
- void collect(@NonNull WindowContainer wc) {
- if (!wc.mTransitionController.isShellTransitionsEnabled()) return;
- if (!expectCollecting()) return;
- getTransition().collect(wc);
- }
-
- /**
- * An interface for creating and tracking action chains.
- */
- static class Tracker {
- private final ActivityTaskManagerService mAtm;
-
- Tracker(ActivityTaskManagerService atm) {
- mAtm = atm;
- }
-
- private ActionChain makeChain(String source, @LinkType int type, Transition transit) {
- final ActionChain out = new ActionChain(source, type, transit);
- if (!Flags.transitTrackerPlumbing()) {
- out.mTmpAtm = mAtm;
- }
- return out;
- }
-
- private ActionChain makeChain(String source, @LinkType int type) {
- return makeChain(source, type,
- mAtm.getTransitionController().getCollectingTransition());
- }
-
- /**
- * Starts tracking a normal action.
- * @see #TYPE_NORMAL
- */
- @NonNull
- ActionChain start(String source, Transition transit) {
- return makeChain(source, TYPE_NORMAL, transit);
- }
-
- /** @see #TYPE_DEFAULT */
- @NonNull
- ActionChain startDefault(String source) {
- return makeChain(source, TYPE_DEFAULT);
- }
-
- /**
- * Starts tracking an action that finishes a transition.
- * @see #TYPE_NORMAL
- */
- @NonNull
- ActionChain startFinish(String source, Transition finishTransit) {
- return makeChain(source, TYPE_FINISH, finishTransit);
- }
-
- /** @see #TYPE_LEGACY */
- @NonNull
- ActionChain startLegacy(String source) {
- return makeChain(source, TYPE_LEGACY, null);
- }
-
- /** @see #TYPE_FAILSAFE */
- @NonNull
- ActionChain startFailsafe(String source) {
- return makeChain(source, TYPE_FAILSAFE);
- }
- }
-
- /** Helpers for usage in tests. */
- @NonNull
- static ActionChain test() {
- return new ActionChain("test", TYPE_TEST, null /* transition */);
- }
-
- @NonNull
- static ActionChain testFinish(Transition toFinish) {
- return new ActionChain("test", TYPE_FINISH, toFinish);
- }
-}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 03c7fd1..0f108c5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -795,7 +795,6 @@
WindowOrganizerController mWindowOrganizerController;
TaskOrganizerController mTaskOrganizerController;
TaskFragmentOrganizerController mTaskFragmentOrganizerController;
- ActionChain.Tracker mChainTracker;
@Nullable
private BackgroundActivityStartCallback mBackgroundActivityStartCallback;
@@ -870,7 +869,6 @@
mInternal = new LocalService();
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
mWindowOrganizerController = new WindowOrganizerController(this);
- mChainTracker = new ActionChain.Tracker(this);
mTaskOrganizerController = mWindowOrganizerController.mTaskOrganizerController;
mTaskFragmentOrganizerController =
mWindowOrganizerController.mTaskFragmentOrganizerController;
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 82ede7e..e25db7e 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -181,7 +181,7 @@
final @TransitionType int mType;
private int mSyncId = -1;
private @TransitionFlags int mFlags;
- final TransitionController mController;
+ private final TransitionController mController;
private final BLASTSyncEngine mSyncEngine;
private final Token mToken;
@@ -329,9 +329,6 @@
*/
ArrayList<ActivityRecord> mConfigAtEndActivities = null;
- /** The current head of the chain of actions related to this transition. */
- ActionChain mChainHead = null;
-
@VisibleForTesting
Transition(@TransitionType int type, @TransitionFlags int flags,
TransitionController controller, BLASTSyncEngine syncEngine) {
@@ -1210,14 +1207,10 @@
* The transition has finished animating and is ready to finalize WM state. This should not
* be called directly; use {@link TransitionController#finishTransition} instead.
*/
- void finishTransition(@NonNull ActionChain chain) {
+ void finishTransition() {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER) && mIsPlayerEnabled) {
asyncTraceEnd(System.identityHashCode(this));
}
- if (!chain.isFinishing()) {
- throw new IllegalStateException("Can't finish on a non-finishing transition "
- + chain.mTransition);
- }
mLogger.mFinishTimeNs = SystemClock.elapsedRealtimeNanos();
mController.mLoggerHandler.post(mLogger::logOnFinish);
mController.mTransitionTracer.logFinishedTransition(this);
@@ -2170,7 +2163,7 @@
if (mFinishTransaction != null) {
mFinishTransaction.apply();
}
- mController.finishTransition(mController.mAtm.mChainTracker.startFinish("clean-up", this));
+ mController.finishTransition(this);
}
private void cleanUpInternal() {
@@ -3386,11 +3379,6 @@
return false;
}
- void recordChain(@NonNull ActionChain chain) {
- chain.mPrevious = mChainHead;
- mChainHead = chain;
- }
-
@VisibleForTesting
static class ChangeInfo {
private static final int FLAG_NONE = 0;
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 56a24dd..9bbf102 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -52,8 +52,8 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.ProtoLog;
import com.android.internal.protolog.ProtoLogGroup;
+import com.android.internal.protolog.ProtoLog;
import com.android.server.FgThread;
import com.android.window.flags.Flags;
@@ -921,12 +921,7 @@
}
/** @see Transition#finishTransition */
- void finishTransition(@NonNull ActionChain chain) {
- if (!chain.isFinishing()) {
- throw new IllegalStateException("Can't finish on a non-finishing transition "
- + chain.mTransition);
- }
- final Transition record = chain.mTransition;
+ void finishTransition(Transition record) {
// It is usually a no-op but make sure that the metric consumer is removed.
mTransitionMetricsReporter.reportAnimationStart(record.getToken(), 0 /* startTime */);
// It is a no-op if the transition did not change the display.
@@ -942,7 +937,7 @@
mTrackCount = 0;
}
updateRunningRemoteAnimation(record, false /* isPlaying */);
- record.finishTransition(chain);
+ record.finishTransition();
for (int i = mAnimatingExitWindows.size() - 1; i >= 0; i--) {
final WindowState w = mAnimatingExitWindows.get(i);
if (w.mAnimatingExit && w.mHasSurface && !w.inTransition()) {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 60ccdc7..e1e64ee 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -223,8 +223,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- final ActionChain chain = mService.mChainTracker.startLegacy("applyTransactLegacy");
- applyTransaction(t, -1 /*syncId*/, chain, caller);
+ applyTransaction(t, -1 /*syncId*/, null /*transition*/, caller);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -243,8 +242,7 @@
try {
synchronized (mGlobalLock) {
if (callback == null) {
- final ActionChain chain = mService.mChainTracker.startLegacy("applySyncLegacy");
- applyTransaction(t, -1 /* syncId*/, chain, caller);
+ applyTransaction(t, -1 /* syncId*/, null /*transition*/, caller);
return -1;
}
@@ -264,15 +262,13 @@
final int syncId = syncGroup.mSyncId;
if (mTransitionController.isShellTransitionsEnabled()) {
mTransitionController.startLegacySyncOrQueue(syncGroup, (deferred) -> {
- applyTransaction(t, syncId, mService.mChainTracker.startLegacy(
- "applySyncLegacy"), caller, deferred);
+ applyTransaction(t, syncId, null /* transition */, caller, deferred);
setSyncReady(syncId);
});
} else {
if (!mService.mWindowManager.mSyncEngine.hasActiveSync()) {
mService.mWindowManager.mSyncEngine.startSyncSet(syncGroup);
- applyTransaction(t, syncId, mService.mChainTracker.startLegacy(
- "applySyncLegacy"), caller);
+ applyTransaction(t, syncId, null /*transition*/, caller);
setSyncReady(syncId);
} else {
// Because the BLAST engine only supports one sync at a time, queue the
@@ -280,8 +276,7 @@
mService.mWindowManager.mSyncEngine.queueSyncSet(
() -> mService.mWindowManager.mSyncEngine.startSyncSet(syncGroup),
() -> {
- applyTransaction(t, syncId, mService.mChainTracker.startLegacy(
- "applySyncLegacy"), caller);
+ applyTransaction(t, syncId, null /*transition*/, caller);
setSyncReady(syncId);
});
}
@@ -318,8 +313,7 @@
throw new IllegalArgumentException("Can't use legacy transitions in"
+ " compatibility mode with no WCT.");
}
- applyTransaction(t, -1 /* syncId */,
- mService.mChainTracker.startLegacy("wrongLegacyTransit"), caller);
+ applyTransaction(t, -1 /* syncId */, null, caller);
return null;
}
final WindowContainerTransaction wct =
@@ -340,11 +334,10 @@
nextTransition.calcParallelCollectType(wct);
mTransitionController.startCollectOrQueue(nextTransition,
(deferred) -> {
- final ActionChain chain = mService.mChainTracker.start(
- "startNewTransit", nextTransition);
nextTransition.start();
nextTransition.mLogger.mStartWCT = wct;
- applyTransaction(wct, -1 /* syncId */, chain, caller, deferred);
+ applyTransaction(wct, -1 /* syncId */, nextTransition, caller,
+ deferred);
wctApplied.meet();
if (needsSetReady) {
setAllReadyIfNeeded(nextTransition, wct);
@@ -358,9 +351,7 @@
Slog.e(TAG, "Trying to start a transition that isn't collecting. This probably"
+ " means Shell took too long to respond to a request. WM State may be"
+ " incorrect now, please file a bug");
- final ActionChain chain = mService.mChainTracker.startFailsafe("startTransit");
- chain.mTransition = null;
- applyTransaction(wct, -1 /*syncId*/, chain, caller);
+ applyTransaction(wct, -1 /*syncId*/, null /*transition*/, caller);
return transition.getToken();
}
// Currently, application of wct can span multiple looper loops (ie.
@@ -376,20 +367,16 @@
if (transition.shouldApplyOnDisplayThread()) {
mService.mH.post(() -> {
synchronized (mService.mGlobalLock) {
- final ActionChain chain = mService.mChainTracker.start(
- "startTransit", transition);
transition.start();
- applyTransaction(wct, -1 /* syncId */, chain, caller);
+ applyTransaction(wct, -1 /* syncId */, transition, caller);
if (wctApplied != null) {
wctApplied.meet();
}
}
});
} else {
- final ActionChain chain = mService.mChainTracker.start("startTransit",
- transition);
transition.start();
- applyTransaction(wct, -1 /* syncId */, chain, caller);
+ applyTransaction(wct, -1 /* syncId */, transition, caller);
if (wctApplied != null) {
wctApplied.meet();
}
@@ -488,8 +475,7 @@
dc.mAppTransition.overridePendingAppTransitionRemote(adapter, true /* sync */,
false /* isActivityEmbedding */);
syncId = startSyncWithOrganizer(callback);
- applyTransaction(t, syncId, mService.mChainTracker.startLegacy("legacyTransit"),
- caller);
+ applyTransaction(t, syncId, null /* transition */, caller);
setSyncReady(syncId);
}
} finally {
@@ -507,8 +493,6 @@
try {
synchronized (mGlobalLock) {
final Transition transition = Transition.fromBinder(transitionToken);
- final ActionChain chain =
- mService.mChainTracker.startFinish("finishTransit", transition);
// apply the incoming transaction before finish in case it alters the visibility
// of the participants.
if (t != null) {
@@ -516,9 +500,9 @@
// changes of the transition participants will only set visible-requested
// and still let finishTransition handle the participants.
mTransitionController.mFinishingTransition = transition;
- applyTransaction(t, -1 /* syncId */, chain, caller);
+ applyTransaction(t, -1 /* syncId */, null /*transition*/, caller, transition);
}
- mTransitionController.finishTransition(chain);
+ mTransitionController.finishTransition(transition);
mTransitionController.mFinishingTransition = null;
}
} finally {
@@ -553,10 +537,9 @@
final CallerInfo caller = new CallerInfo();
final long ident = Binder.clearCallingIdentity();
try {
- if (!mTransitionController.isShellTransitionsEnabled()) {
+ if (mTransitionController.getTransitionPlayer() == null) {
// No need to worry about transition when Shell transition is not enabled.
- applyTransaction(wct, -1 /* syncId */,
- mService.mChainTracker.startLegacy("legacyTFTransact"), caller);
+ applyTransaction(wct, -1 /* syncId */, null /* transition */, caller);
return;
}
@@ -565,8 +548,8 @@
// Although there is an active sync, we want to apply the transaction now.
// TODO(b/232042367) Redesign the organizer update on activity callback so that we
// we will know about the transition explicitly.
- final ActionChain chain = mService.mChainTracker.startDefault("tfTransact");
- if (chain.mTransition == null) {
+ final Transition transition = mTransitionController.getCollectingTransition();
+ if (transition == null) {
// This should rarely happen, and we should try to avoid using
// {@link #applySyncTransaction} with Shell transition.
// We still want to apply and merge the transaction to the active sync
@@ -576,7 +559,7 @@
+ " because there is an ongoing sync for"
+ " applySyncTransaction().");
}
- applyTransaction(wct, -1 /* syncId */, chain, caller);
+ applyTransaction(wct, -1 /* syncId */, transition, caller);
return;
}
@@ -587,9 +570,8 @@
transition.abort();
return;
}
- final ActionChain chain = mService.mChainTracker.start("tfTransact", transition);
- final int effects = applyTransaction(wct, -1 /* syncId */, chain, caller, deferred);
- if (effects == TRANSACT_EFFECTS_NONE && transition.mParticipants.isEmpty()) {
+ if (applyTransaction(wct, -1 /* syncId */, transition, caller, deferred)
+ == TRANSACT_EFFECTS_NONE && transition.mParticipants.isEmpty()) {
transition.abort();
return;
}
@@ -604,10 +586,15 @@
}
private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
- @NonNull ActionChain chain, @NonNull CallerInfo caller, boolean deferred) {
+ @Nullable Transition transition, @NonNull CallerInfo caller) {
+ return applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
+ }
+
+ private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
+ @Nullable Transition transition, @NonNull CallerInfo caller, boolean deferred) {
if (deferred) {
try {
- return applyTransaction(t, syncId, chain, caller);
+ return applyTransaction(t, syncId, transition, caller);
} catch (RuntimeException e) {
// If the transaction is deferred, the caller could be from TransitionController
// #tryStartCollectFromQueue that executes on system's worker thread rather than
@@ -617,17 +604,19 @@
}
return TRANSACT_EFFECTS_NONE;
}
- return applyTransaction(t, syncId, chain, caller);
+ return applyTransaction(t, syncId, transition, caller);
}
/**
* @param syncId If non-null, this will be a sync-transaction.
- * @param chain A lifecycle-chain to acculumate changes into.
+ * @param transition A transition to collect changes into.
* @param caller Info about the calling process.
+ * @param finishTransition The transition that is currently being finished.
* @return The effects of the window container transaction.
*/
private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
- @NonNull ActionChain chain, @NonNull CallerInfo caller) {
+ @Nullable Transition transition, @NonNull CallerInfo caller,
+ @Nullable Transition finishTransition) {
int effects = TRANSACT_EFFECTS_NONE;
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
mService.deferWindowLayout();
@@ -635,21 +624,20 @@
boolean deferResume = true;
mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */);
boolean deferTransitionReady = false;
- if (chain.mTransition != null && !t.isEmpty() && !chain.isFinishing()) {
- if (chain.mTransition.isCollecting()) {
+ if (transition != null && !t.isEmpty()) {
+ if (transition.isCollecting()) {
deferTransitionReady = true;
- chain.mTransition.deferTransitionReady();
+ transition.deferTransitionReady();
} else {
Slog.w(TAG, "Transition is not collecting when applyTransaction."
- + " transition=" + chain.mTransition + " state="
- + chain.mTransition.getState());
- chain.mTransition = null;
+ + " transition=" + transition + " state=" + transition.getState());
+ transition = null;
}
}
try {
final ArraySet<WindowContainer<?>> haveConfigChanges = new ArraySet<>();
- if (chain.mTransition != null) {
- chain.mTransition.applyDisplayChangeIfNeeded(haveConfigChanges);
+ if (transition != null) {
+ transition.applyDisplayChangeIfNeeded(haveConfigChanges);
if (!haveConfigChanges.isEmpty()) {
effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
}
@@ -657,7 +645,7 @@
final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
final int hopSize = hops.size();
Iterator<Map.Entry<IBinder, WindowContainerTransaction.Change>> entries;
- if (chain.mTransition != null) {
+ if (transition != null) {
// Mark any config-at-end containers before applying config changes so that
// the config changes don't dispatch to client.
entries = t.getChanges().entrySet().iterator();
@@ -667,7 +655,7 @@
if (!entry.getValue().getConfigAtTransitionEnd()) continue;
final WindowContainer wc = WindowContainer.fromBinder(entry.getKey());
if (wc == null || !wc.isAttached()) continue;
- chain.mTransition.setConfigAtEnd(wc);
+ transition.setConfigAtEnd(wc);
}
}
entries = t.getChanges().entrySet().iterator();
@@ -684,13 +672,15 @@
if (syncId >= 0) {
addToSyncSet(syncId, wc);
}
- chain.collect(wc);
+ if (transition != null) transition.collect(wc);
if ((entry.getValue().getChangeMask()
& WindowContainerTransaction.Change.CHANGE_FORCE_NO_PIP) != 0) {
// Disable entering pip (eg. when recents pretends to finish itself)
- if (chain.mTransition != null) {
- chain.mTransition.setCanPipOnFinish(false /* canPipOnFinish */);
+ if (finishTransition != null) {
+ finishTransition.setCanPipOnFinish(false /* canPipOnFinish */);
+ } else if (transition != null) {
+ transition.setCanPipOnFinish(false /* canPipOnFinish */);
}
}
// A bit hacky, but we need to detect "remove PiP" so that we can "wrap" the
@@ -738,9 +728,9 @@
if (hopSize > 0) {
final boolean isInLockTaskMode = mService.isInLockTaskMode();
for (int i = 0; i < hopSize; ++i) {
- effects |= applyHierarchyOp(hops.get(i), effects, syncId, chain,
+ effects |= applyHierarchyOp(hops.get(i), effects, syncId, transition,
isInLockTaskMode, caller, t.getErrorCallbackToken(),
- t.getTaskFragmentOrganizer());
+ t.getTaskFragmentOrganizer(), finishTransition);
}
}
// Queue-up bounds-change transactions for tasks which are now organized. Do
@@ -799,7 +789,7 @@
}
} finally {
if (deferTransitionReady) {
- chain.mTransition.continueTransitionReady();
+ transition.continueTransitionReady();
}
mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
if (deferResume) {
@@ -1089,9 +1079,9 @@
}
private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
- int syncId, @NonNull ActionChain chain, boolean isInLockTaskMode,
+ int syncId, @Nullable Transition transition, boolean isInLockTaskMode,
@NonNull CallerInfo caller, @Nullable IBinder errorCallbackToken,
- @Nullable ITaskFragmentOrganizer organizer) {
+ @Nullable ITaskFragmentOrganizer organizer, @Nullable Transition finishTransition) {
final int type = hop.getType();
switch (type) {
case HIERARCHY_OP_TYPE_REMOVE_TASK: {
@@ -1161,7 +1151,7 @@
break;
}
case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: {
- effects |= reparentChildrenTasksHierarchyOp(hop, chain.mTransition, syncId,
+ effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId,
isInLockTaskMode);
break;
}
@@ -1214,13 +1204,13 @@
if (syncId >= 0) {
addToSyncSet(syncId, wc);
}
- if (chain.mTransition != null) {
- chain.mTransition.collect(wc);
+ if (transition != null) {
+ transition.collect(wc);
if (hop.isReparent()) {
if (wc.getParent() != null) {
// Collect the current parent. It's visibility may change as
// a result of this reparenting.
- chain.mTransition.collect(wc.getParent());
+ transition.collect(wc.getParent());
}
if (hop.getNewParent() != null) {
final WindowContainer parentWc =
@@ -1229,7 +1219,7 @@
Slog.e(TAG, "Can't resolve parent window from token");
break;
}
- chain.mTransition.collect(parentWc);
+ transition.collect(parentWc);
}
}
}
@@ -1243,8 +1233,8 @@
break;
}
case HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION: {
- effects |= applyTaskFragmentOperation(hop, chain, isInLockTaskMode,
- caller, errorCallbackToken, organizer);
+ effects |= applyTaskFragmentOperation(hop, transition, isInLockTaskMode, caller,
+ errorCallbackToken, organizer);
break;
}
case HIERARCHY_OP_TYPE_PENDING_INTENT: {
@@ -1358,13 +1348,13 @@
break;
}
case HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER: {
- if (!chain.isFinishing()) break;
+ if (finishTransition == null) break;
final WindowContainer container = WindowContainer.fromBinder(hop.getContainer());
if (container == null) break;
final Task thisTask = container.asActivityRecord() != null
? container.asActivityRecord().getTask() : container.asTask();
if (thisTask == null) break;
- final Task restoreAt = chain.mTransition.getTransientLaunchRestoreTarget(container);
+ final Task restoreAt = finishTransition.getTransientLaunchRestoreTarget(container);
if (restoreAt == null) break;
final TaskDisplayArea taskDisplayArea = thisTask.getTaskDisplayArea();
taskDisplayArea.moveRootTaskBehindRootTask(thisTask.getRootTask(), restoreAt);
@@ -1454,7 +1444,7 @@
* {@link #TRANSACT_EFFECTS_LIFECYCLE} or {@link #TRANSACT_EFFECTS_CLIENT_CONFIG}.
*/
private int applyTaskFragmentOperation(@NonNull WindowContainerTransaction.HierarchyOp hop,
- @NonNull ActionChain chain, boolean isInLockTaskMode, @NonNull CallerInfo caller,
+ @Nullable Transition transition, boolean isInLockTaskMode, @NonNull CallerInfo caller,
@Nullable IBinder errorCallbackToken, @Nullable ITaskFragmentOrganizer organizer) {
if (!validateTaskFragmentOperation(hop, errorCallbackToken, organizer)) {
return TRANSACT_EFFECTS_NONE;
@@ -1477,7 +1467,7 @@
break;
}
createTaskFragment(taskFragmentCreationParams, errorCallbackToken, caller,
- chain.mTransition);
+ transition);
break;
}
case OP_TYPE_DELETE_TASK_FRAGMENT: {
@@ -1494,7 +1484,7 @@
break;
}
}
- effects |= deleteTaskFragment(taskFragment, chain.mTransition);
+ effects |= deleteTaskFragment(taskFragment, transition);
break;
}
case OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT: {
@@ -1543,14 +1533,14 @@
opType, exception);
break;
}
- if (chain.mTransition != null) {
- chain.collect(activity);
+ if (transition != null) {
+ transition.collect(activity);
if (activity.getParent() != null) {
// Collect the current parent. Its visibility may change as a result of
// this reparenting.
- chain.collect(activity.getParent());
+ transition.collect(activity.getParent());
}
- chain.collect(taskFragment);
+ transition.collect(taskFragment);
}
activity.reparent(taskFragment, POSITION_TOP);
effects |= TRANSACT_EFFECTS_LIFECYCLE;
@@ -1706,8 +1696,8 @@
// If any TaskFragment in the Task is collected by the transition, we make the decor
// surface visible in sync with the TaskFragment transition. Otherwise, we make the
// decor surface visible immediately.
- final TaskFragment syncTaskFragment = chain.mTransition != null
- ? task.getTaskFragment(chain.mTransition.mParticipants::contains)
+ final TaskFragment syncTaskFragment = transition != null
+ ? task.getTaskFragment(transition.mParticipants::contains)
: null;
if (syncTaskFragment != null) {
@@ -1759,7 +1749,7 @@
// The decor surface boost/unboost must be applied after the transition is
// completed. Otherwise, the decor surface could be moved before Shell completes
// the transition, causing flicker.
- runAfterTransition(chain.mTransition, task::commitDecorSurfaceBoostedState);
+ runAfterTransition(transition, task::commitDecorSurfaceBoostedState);
}
break;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 52a80b0..56fca31 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -1251,7 +1251,7 @@
final Transition transition = app.mTransitionController.createTransition(TRANSIT_OPEN);
app.mTransitionController.requestStartTransition(transition, app.getTask(),
null /* remoteTransition */, null /* displayChange */);
- transition.collectExistenceChange(app.getTask());
+ app.mTransitionController.collectExistenceChange(app.getTask());
mDisplayContent.setFixedRotationLaunchingAppUnchecked(app);
final AsyncRotationController asyncRotationController =
mDisplayContent.getAsyncRotationController();
@@ -1416,8 +1416,7 @@
activity1.setVisibleRequested(false);
activity2.setVisibleRequested(true);
- final ActionChain chain = ActionChain.testFinish(null);
- openTransition.finishTransition(chain);
+ openTransition.finishTransition();
// We finished the openTransition. Even though activity1 is visibleRequested=false, since
// the closeTransition animation hasn't played yet, make sure that we didn't commit
@@ -1430,7 +1429,7 @@
// normally.
mWm.mSyncEngine.abort(closeTransition.getSyncId());
- closeTransition.finishTransition(chain);
+ closeTransition.finishTransition();
assertFalse(activity1.isVisible());
assertTrue(activity2.isVisible());
@@ -1450,7 +1449,7 @@
activity1.setState(ActivityRecord.State.INITIALIZING, "test");
activity1.mLaunchTaskBehind = true;
mWm.mSyncEngine.abort(noChangeTransition.getSyncId());
- noChangeTransition.finishTransition(chain);
+ noChangeTransition.finishTransition();
assertTrue(activity1.mLaunchTaskBehind);
}
@@ -1469,7 +1468,7 @@
// We didn't call abort on the transition itself, so it will still run onTransactionReady
// normally.
mWm.mSyncEngine.abort(transition1.getSyncId());
- transition1.finishTransition(ActionChain.testFinish(transition1));
+ transition1.finishTransition();
verify(transitionEndedListener).run();
@@ -1531,7 +1530,7 @@
verify(taskSnapshotController, times(1)).recordSnapshot(eq(task2));
- controller.finishTransition(ActionChain.testFinish(openTransition));
+ controller.finishTransition(openTransition);
// We are now going to simulate closing task1 to return back to (open) task2.
final Transition closeTransition = createTestTransition(TRANSIT_CLOSE, controller);
@@ -1596,7 +1595,7 @@
doReturn(true).when(task1).isTranslucentForTransition();
assertFalse(controller.canApplyDim(task1));
- controller.finishTransition(ActionChain.testFinish(closeTransition));
+ controller.finishTransition(closeTransition);
assertTrue(wasInFinishingTransition[0]);
assertFalse(calledListenerOnOtherDisplay[0]);
assertNull(controller.mFinishingTransition);
@@ -1652,7 +1651,7 @@
// to avoid the latency to resume the current top, i.e. appB.
assertTrue(controller.isTransientVisible(taskRecent));
// The recent is paused after the transient transition is finished.
- controller.finishTransition(ActionChain.testFinish(transition));
+ controller.finishTransition(transition);
assertFalse(controller.isTransientVisible(taskRecent));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 9602ae2..7652861 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -407,7 +407,7 @@
final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
token.finishSync(t, token.getSyncGroup(), false /* cancel */);
transit.onTransactionReady(transit.getSyncId(), t);
- dc.mTransitionController.finishTransition(ActionChain.testFinish(transit));
+ dc.mTransitionController.finishTransition(transit);
assertFalse(wallpaperWindow.isVisible());
assertFalse(token.isVisible());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index a215c0a..bcf4ebc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -2131,7 +2131,7 @@
}
public void finish() {
- mController.finishTransition(ActionChain.testFinish(mLastTransit));
+ mController.finishTransition(mLastTransit);
}
}
}