Loading services/core/java/com/android/server/wm/ActionChain.java +43 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,20 @@ public class ActionChain { } } void attachTransition(Transition transit) { if (mTransition != null) { throw new IllegalStateException("can't attach transition to chain that is already" + " attached to a transition"); } if (mPrevious != null) { throw new IllegalStateException("Can only attach transition to the head of a chain"); } mTransition = transit; if (mTransition != null) { mTransition.recordChain(this); } } @Nullable Transition getTransition() { if (!Flags.transitTrackerPlumbing()) { Loading @@ -148,6 +162,11 @@ public class ActionChain { return transition != null && transition.isCollecting(); } /** Returns {@code true} if the display contains a collecting transition. */ boolean isCollectingOnDisplay(@NonNull DisplayContent dc) { return isCollecting() && getTransition().isOnDisplay(dc); } /** * Some common checks to determine (and report) whether this chain has a collecting transition. * Returns the collecting transition or {@code null} if there is an issue. Loading Loading @@ -182,6 +201,21 @@ public class ActionChain { transition.collect(wc); } /** * Collects a window container which will be removed or invisible. */ void collectClose(@NonNull WindowContainer<?> wc) { if (!wc.mTransitionController.isShellTransitionsEnabled()) return; final Transition transition = expectCollecting(); if (wc.isVisibleRequested()) { transition.collectExistenceChange(wc); } else { // Removing a non-visible window doesn't require a transition, but if there is one // collecting, this should be a member just in case. collect(wc); } } private static class AsyncStart { final int mStackPos; long mThreadId; Loading Loading @@ -339,6 +373,15 @@ public class ActionChain { return makeChain(source, TYPE_DEFAULT); } /** * Create a chain-link for a decision-point between making a new transition or using the * global collecting one. */ @NonNull ActionChain startTransit(String source) { return makeChain(source, TYPE_DEFAULT); } /** * Starts tracking an action that finishes a transition. * @see #TYPE_NORMAL Loading services/core/java/com/android/server/wm/ActivityClientController.java +15 −3 Original line number Diff line number Diff line Loading @@ -858,13 +858,17 @@ class ActivityClientController extends IActivityClientController.Stub { if (r == null) { return false; } final ActionChain chain = mService.mChainTracker.startTransit("fromTransluce"); // Create a transition if the activity is playing in case the below activity didn't // commit invisible. That's because if any activity below this one has changed its // visibility while playing transition, there won't able to commit visibility until // the running transition finish. final Transition transition = r.mTransitionController.isShellTransitionsEnabled() && !r.mTransitionController.isCollecting() && !chain.isCollecting() ? r.mTransitionController.createTransition(TRANSIT_TO_BACK) : null; if (transition != null) { chain.attachTransition(transition); } final boolean changed = r.setOccludesParent(true); if (transition != null) { if (changed) { Loading @@ -880,6 +884,7 @@ class ActivityClientController extends IActivityClientController.Stub { transition.abort(); } } mService.mChainTracker.end(); return changed; } } finally { Loading @@ -904,10 +909,14 @@ class ActivityClientController extends IActivityClientController.Stub { if (under != null) { under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null; } final ActionChain chain = mService.mChainTracker.startTransit("toTransluce"); // Create a transition to make sure the activity change is collected. final Transition transition = r.mTransitionController.isShellTransitionsEnabled() && !r.mTransitionController.isCollecting() && !chain.isCollecting() ? r.mTransitionController.createTransition(TRANSIT_TO_FRONT) : null; if (transition != null) { chain.attachTransition(transition); } final boolean changed = r.setOccludesParent(false); if (transition != null) { if (changed) { Loading @@ -927,6 +936,7 @@ class ActivityClientController extends IActivityClientController.Stub { transition.abort(); } } mService.mChainTracker.end(); return changed; } } finally { Loading Loading @@ -1270,12 +1280,14 @@ class ActivityClientController extends IActivityClientController.Stub { transition.abort(); return; } final ActionChain chain = mService.mChainTracker.start("reqMWFS", transition); final Task requestingTask = r.getTask(); transition.collect(requestingTask); chain.collect(requestingTask); executeMultiWindowFullscreenRequest(fullscreenRequest, requestingTask); r.mTransitionController.requestStartTransition(transition, requestingTask, null /* remoteTransition */, null /* displayChange */); transition.setReady(requestingTask, true); mService.mChainTracker.end(); } private static void reportMultiwindowFullscreenRequestValidatingResult(IRemoteCallback callback, Loading services/core/java/com/android/server/wm/ActivityRecord.java +19 −12 Original line number Diff line number Diff line Loading @@ -3574,6 +3574,7 @@ final class ActivityRecord extends WindowToken { // root task is not visible if it only contains finishing activities. && mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask); final ActionChain chain = mAtmService.mChainTracker.startTransit("AR.finish"); mAtmService.deferWindowLayout(); try { mTaskSupervisor.mNoHistoryActivities.remove(this); Loading @@ -3598,12 +3599,14 @@ final class ActivityRecord extends WindowToken { final boolean endTask = task.getTopNonFinishingActivity() == null && !task.isClearingToReuseTask(); final WindowContainer<?> trigger = endTask ? task : this; final Transition newTransition = mTransitionController.requestCloseTransitionIfNeeded(trigger); final Transition transition = newTransition != null ? newTransition : mTransitionController.getCollectingTransition(); if (transition != null) { transition.collectClose(trigger); Transition newTransition = null; if (!chain.isCollecting()) { chain.attachTransition( mTransitionController.requestCloseTransitionIfNeeded(trigger)); newTransition = chain.getTransition(); } if (chain.isCollecting()) { chain.getTransition().collectClose(trigger); } // We are finishing the top focused activity and its task has nothing to be focused so // the next focusable task should be focused. Loading Loading @@ -3706,6 +3709,7 @@ final class ActivityRecord extends WindowToken { return FINISH_RESULT_REQUESTED; } finally { mAtmService.continueWindowLayout(); mAtmService.mChainTracker.endPartial(); } } Loading Loading @@ -4291,12 +4295,11 @@ final class ActivityRecord extends WindowToken { // closing the task. final WindowContainer trigger = remove && task != null && task.getChildCount() == 1 ? task : this; final Transition tr = mTransitionController.requestCloseTransitionIfNeeded(trigger); if (tr != null) { tr.collectClose(trigger); } else if (mTransitionController.isCollecting()) { mTransitionController.getCollectingTransition().collectClose(trigger); final ActionChain chain = mAtmService.mChainTracker.startTransit("appDied"); if (!chain.isCollecting()) { chain.attachTransition(mTransitionController.requestCloseTransitionIfNeeded(trigger)); } chain.collectClose(trigger); cleanUp(true /* cleanServices */, true /* setState */); if (remove) { if (mStartingData != null && mVisible && task != null) { Loading @@ -4311,6 +4314,7 @@ final class ActivityRecord extends WindowToken { } removeFromHistory("appDied"); } mAtmService.mChainTracker.end(); } @Override Loading Loading @@ -8865,13 +8869,16 @@ final class ActivityRecord extends WindowToken { transition.abort(); return; } final ActionChain chain = mAtmService.mChainTracker.start( "restartProc", transition); // Request invisible so there will be a change after the activity is restarted // to be visible. setVisibleRequested(false); transition.collect(this); chain.collect(this); mTransitionController.requestStartTransition(transition, task, null /* remoteTransition */, null /* displayChange */); scheduleStopForRestartProcess(); mAtmService.mChainTracker.end(); }); } else { scheduleStopForRestartProcess(); Loading services/core/java/com/android/server/wm/ActivityStarter.java +14 −9 Original line number Diff line number Diff line Loading @@ -1508,21 +1508,26 @@ class ActivityStarter { mService.resumeAppSwitches(); } // Only do the create here since startActivityInner can abort. If it doesn't abort, // the requestStart will be sent in handleStartRequest. final Transition newTransition = r.mTransitionController.isShellTransitionsEnabled() ? r.mTransitionController.createAndStartCollecting(TRANSIT_OPEN) : null; final ActionChain chain = mService.mChainTracker.startTransit("startAct"); // Because startActivity must run immediately, it can get combined with another // transition meaning it is no-longer independent. This is NOT desirable, but is the // only option for the time being. final boolean isIndependent = newTransition != null; final Transition transition = isIndependent ? newTransition : mService.getTransitionController().getCollectingTransition(); boolean isIndependent = false; if (!chain.isCollecting()) { // Only do the create here since startActivityInner can abort. If it doesn't abort, // the requestStart will be sent in handleStartRequest. chain.attachTransition(r.mTransitionController.createAndStartCollecting(TRANSIT_OPEN)); isIndependent = chain.getTransition() != null; } mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, request.voiceInteractor, startFlags, checkedOptions, inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid, transition, isIndependent); inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid, chain.getTransition(), isIndependent); // Because the pending-intent usage in the waitAsyncStart hack "exits" ATMS into // AMS and re-enters, this can be nested. mService.mChainTracker.endPartial(); if (request.outActivity != null) { request.outActivity[0] = mLastStartActivityRecord; Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +15 −4 Original line number Diff line number Diff line Loading @@ -2112,10 +2112,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { setLastResumedActivityUncheckLocked(r, "setFocusedTask-alreadyTop"); return; } final Transition transition = (getTransitionController().isCollecting() || !getTransitionController().isShellTransitionsEnabled()) ? null : getTransitionController().createTransition(TRANSIT_TO_FRONT); final ActionChain chain = mChainTracker.startTransit("setFocusedTask"); final Transition transition = (!chain.isCollecting() && getTransitionController().isShellTransitionsEnabled()) ? getTransitionController().createTransition(TRANSIT_TO_FRONT) : null; if (transition != null) { chain.attachTransition(transition); // Set ready before doing anything. If order does change, then that will set it unready // so that we wait for the new lifecycles to complete. transition.setReady(task, true /* ready */); Loading @@ -2137,6 +2139,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { true /* updateInputWindows */); } } mChainTracker.end(); if (transition != null && !movedToTop) { // No order changes and focus-changes, alone, aren't captured in transitions. transition.abort(); Loading Loading @@ -2993,11 +2996,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { transition.abort(); return; } final ActionChain chain = mChainTracker.start("resizeTask", transition); getTransitionController().requestStartTransition(transition, task, null /* remoteTransition */, null /* displayChange */); transition.collect(task); chain.collect(task); task.resize(bounds, resizeMode, preserveWindow); transition.setReady(task, true); mChainTracker.end(); }); } } finally { Loading Loading @@ -3859,8 +3864,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } getTransitionController().startCollectOrQueue(enterPipTransition, (deferred) -> { mChainTracker.start("enterPip2", enterPipTransition); getTransitionController().requestStartTransition(enterPipTransition, r.getTask(), null /* remoteTransition */, null /* displayChange */); mChainTracker.end(); }); return true; } Loading Loading @@ -3900,6 +3907,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { r.mAutoEnteringPip = isAutoEnter; if (transition != null) { mChainTracker.start("enterPip1", transition); mRootWindowContainer.moveActivityToPinnedRootTaskAndRequestStart(r, "enterPictureInPictureMode"); } else if (getTransitionController().isCollecting() Loading @@ -3921,6 +3929,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { "auto-pip"); } r.mAutoEnteringPip = false; if (transition != null) { mChainTracker.end(); } } }; Loading Loading
services/core/java/com/android/server/wm/ActionChain.java +43 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,20 @@ public class ActionChain { } } void attachTransition(Transition transit) { if (mTransition != null) { throw new IllegalStateException("can't attach transition to chain that is already" + " attached to a transition"); } if (mPrevious != null) { throw new IllegalStateException("Can only attach transition to the head of a chain"); } mTransition = transit; if (mTransition != null) { mTransition.recordChain(this); } } @Nullable Transition getTransition() { if (!Flags.transitTrackerPlumbing()) { Loading @@ -148,6 +162,11 @@ public class ActionChain { return transition != null && transition.isCollecting(); } /** Returns {@code true} if the display contains a collecting transition. */ boolean isCollectingOnDisplay(@NonNull DisplayContent dc) { return isCollecting() && getTransition().isOnDisplay(dc); } /** * Some common checks to determine (and report) whether this chain has a collecting transition. * Returns the collecting transition or {@code null} if there is an issue. Loading Loading @@ -182,6 +201,21 @@ public class ActionChain { transition.collect(wc); } /** * Collects a window container which will be removed or invisible. */ void collectClose(@NonNull WindowContainer<?> wc) { if (!wc.mTransitionController.isShellTransitionsEnabled()) return; final Transition transition = expectCollecting(); if (wc.isVisibleRequested()) { transition.collectExistenceChange(wc); } else { // Removing a non-visible window doesn't require a transition, but if there is one // collecting, this should be a member just in case. collect(wc); } } private static class AsyncStart { final int mStackPos; long mThreadId; Loading Loading @@ -339,6 +373,15 @@ public class ActionChain { return makeChain(source, TYPE_DEFAULT); } /** * Create a chain-link for a decision-point between making a new transition or using the * global collecting one. */ @NonNull ActionChain startTransit(String source) { return makeChain(source, TYPE_DEFAULT); } /** * Starts tracking an action that finishes a transition. * @see #TYPE_NORMAL Loading
services/core/java/com/android/server/wm/ActivityClientController.java +15 −3 Original line number Diff line number Diff line Loading @@ -858,13 +858,17 @@ class ActivityClientController extends IActivityClientController.Stub { if (r == null) { return false; } final ActionChain chain = mService.mChainTracker.startTransit("fromTransluce"); // Create a transition if the activity is playing in case the below activity didn't // commit invisible. That's because if any activity below this one has changed its // visibility while playing transition, there won't able to commit visibility until // the running transition finish. final Transition transition = r.mTransitionController.isShellTransitionsEnabled() && !r.mTransitionController.isCollecting() && !chain.isCollecting() ? r.mTransitionController.createTransition(TRANSIT_TO_BACK) : null; if (transition != null) { chain.attachTransition(transition); } final boolean changed = r.setOccludesParent(true); if (transition != null) { if (changed) { Loading @@ -880,6 +884,7 @@ class ActivityClientController extends IActivityClientController.Stub { transition.abort(); } } mService.mChainTracker.end(); return changed; } } finally { Loading @@ -904,10 +909,14 @@ class ActivityClientController extends IActivityClientController.Stub { if (under != null) { under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null; } final ActionChain chain = mService.mChainTracker.startTransit("toTransluce"); // Create a transition to make sure the activity change is collected. final Transition transition = r.mTransitionController.isShellTransitionsEnabled() && !r.mTransitionController.isCollecting() && !chain.isCollecting() ? r.mTransitionController.createTransition(TRANSIT_TO_FRONT) : null; if (transition != null) { chain.attachTransition(transition); } final boolean changed = r.setOccludesParent(false); if (transition != null) { if (changed) { Loading @@ -927,6 +936,7 @@ class ActivityClientController extends IActivityClientController.Stub { transition.abort(); } } mService.mChainTracker.end(); return changed; } } finally { Loading Loading @@ -1270,12 +1280,14 @@ class ActivityClientController extends IActivityClientController.Stub { transition.abort(); return; } final ActionChain chain = mService.mChainTracker.start("reqMWFS", transition); final Task requestingTask = r.getTask(); transition.collect(requestingTask); chain.collect(requestingTask); executeMultiWindowFullscreenRequest(fullscreenRequest, requestingTask); r.mTransitionController.requestStartTransition(transition, requestingTask, null /* remoteTransition */, null /* displayChange */); transition.setReady(requestingTask, true); mService.mChainTracker.end(); } private static void reportMultiwindowFullscreenRequestValidatingResult(IRemoteCallback callback, Loading
services/core/java/com/android/server/wm/ActivityRecord.java +19 −12 Original line number Diff line number Diff line Loading @@ -3574,6 +3574,7 @@ final class ActivityRecord extends WindowToken { // root task is not visible if it only contains finishing activities. && mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask); final ActionChain chain = mAtmService.mChainTracker.startTransit("AR.finish"); mAtmService.deferWindowLayout(); try { mTaskSupervisor.mNoHistoryActivities.remove(this); Loading @@ -3598,12 +3599,14 @@ final class ActivityRecord extends WindowToken { final boolean endTask = task.getTopNonFinishingActivity() == null && !task.isClearingToReuseTask(); final WindowContainer<?> trigger = endTask ? task : this; final Transition newTransition = mTransitionController.requestCloseTransitionIfNeeded(trigger); final Transition transition = newTransition != null ? newTransition : mTransitionController.getCollectingTransition(); if (transition != null) { transition.collectClose(trigger); Transition newTransition = null; if (!chain.isCollecting()) { chain.attachTransition( mTransitionController.requestCloseTransitionIfNeeded(trigger)); newTransition = chain.getTransition(); } if (chain.isCollecting()) { chain.getTransition().collectClose(trigger); } // We are finishing the top focused activity and its task has nothing to be focused so // the next focusable task should be focused. Loading Loading @@ -3706,6 +3709,7 @@ final class ActivityRecord extends WindowToken { return FINISH_RESULT_REQUESTED; } finally { mAtmService.continueWindowLayout(); mAtmService.mChainTracker.endPartial(); } } Loading Loading @@ -4291,12 +4295,11 @@ final class ActivityRecord extends WindowToken { // closing the task. final WindowContainer trigger = remove && task != null && task.getChildCount() == 1 ? task : this; final Transition tr = mTransitionController.requestCloseTransitionIfNeeded(trigger); if (tr != null) { tr.collectClose(trigger); } else if (mTransitionController.isCollecting()) { mTransitionController.getCollectingTransition().collectClose(trigger); final ActionChain chain = mAtmService.mChainTracker.startTransit("appDied"); if (!chain.isCollecting()) { chain.attachTransition(mTransitionController.requestCloseTransitionIfNeeded(trigger)); } chain.collectClose(trigger); cleanUp(true /* cleanServices */, true /* setState */); if (remove) { if (mStartingData != null && mVisible && task != null) { Loading @@ -4311,6 +4314,7 @@ final class ActivityRecord extends WindowToken { } removeFromHistory("appDied"); } mAtmService.mChainTracker.end(); } @Override Loading Loading @@ -8865,13 +8869,16 @@ final class ActivityRecord extends WindowToken { transition.abort(); return; } final ActionChain chain = mAtmService.mChainTracker.start( "restartProc", transition); // Request invisible so there will be a change after the activity is restarted // to be visible. setVisibleRequested(false); transition.collect(this); chain.collect(this); mTransitionController.requestStartTransition(transition, task, null /* remoteTransition */, null /* displayChange */); scheduleStopForRestartProcess(); mAtmService.mChainTracker.end(); }); } else { scheduleStopForRestartProcess(); Loading
services/core/java/com/android/server/wm/ActivityStarter.java +14 −9 Original line number Diff line number Diff line Loading @@ -1508,21 +1508,26 @@ class ActivityStarter { mService.resumeAppSwitches(); } // Only do the create here since startActivityInner can abort. If it doesn't abort, // the requestStart will be sent in handleStartRequest. final Transition newTransition = r.mTransitionController.isShellTransitionsEnabled() ? r.mTransitionController.createAndStartCollecting(TRANSIT_OPEN) : null; final ActionChain chain = mService.mChainTracker.startTransit("startAct"); // Because startActivity must run immediately, it can get combined with another // transition meaning it is no-longer independent. This is NOT desirable, but is the // only option for the time being. final boolean isIndependent = newTransition != null; final Transition transition = isIndependent ? newTransition : mService.getTransitionController().getCollectingTransition(); boolean isIndependent = false; if (!chain.isCollecting()) { // Only do the create here since startActivityInner can abort. If it doesn't abort, // the requestStart will be sent in handleStartRequest. chain.attachTransition(r.mTransitionController.createAndStartCollecting(TRANSIT_OPEN)); isIndependent = chain.getTransition() != null; } mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, request.voiceInteractor, startFlags, checkedOptions, inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid, transition, isIndependent); inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid, chain.getTransition(), isIndependent); // Because the pending-intent usage in the waitAsyncStart hack "exits" ATMS into // AMS and re-enters, this can be nested. mService.mChainTracker.endPartial(); if (request.outActivity != null) { request.outActivity[0] = mLastStartActivityRecord; Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +15 −4 Original line number Diff line number Diff line Loading @@ -2112,10 +2112,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { setLastResumedActivityUncheckLocked(r, "setFocusedTask-alreadyTop"); return; } final Transition transition = (getTransitionController().isCollecting() || !getTransitionController().isShellTransitionsEnabled()) ? null : getTransitionController().createTransition(TRANSIT_TO_FRONT); final ActionChain chain = mChainTracker.startTransit("setFocusedTask"); final Transition transition = (!chain.isCollecting() && getTransitionController().isShellTransitionsEnabled()) ? getTransitionController().createTransition(TRANSIT_TO_FRONT) : null; if (transition != null) { chain.attachTransition(transition); // Set ready before doing anything. If order does change, then that will set it unready // so that we wait for the new lifecycles to complete. transition.setReady(task, true /* ready */); Loading @@ -2137,6 +2139,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { true /* updateInputWindows */); } } mChainTracker.end(); if (transition != null && !movedToTop) { // No order changes and focus-changes, alone, aren't captured in transitions. transition.abort(); Loading Loading @@ -2993,11 +2996,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { transition.abort(); return; } final ActionChain chain = mChainTracker.start("resizeTask", transition); getTransitionController().requestStartTransition(transition, task, null /* remoteTransition */, null /* displayChange */); transition.collect(task); chain.collect(task); task.resize(bounds, resizeMode, preserveWindow); transition.setReady(task, true); mChainTracker.end(); }); } } finally { Loading Loading @@ -3859,8 +3864,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } getTransitionController().startCollectOrQueue(enterPipTransition, (deferred) -> { mChainTracker.start("enterPip2", enterPipTransition); getTransitionController().requestStartTransition(enterPipTransition, r.getTask(), null /* remoteTransition */, null /* displayChange */); mChainTracker.end(); }); return true; } Loading Loading @@ -3900,6 +3907,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { r.mAutoEnteringPip = isAutoEnter; if (transition != null) { mChainTracker.start("enterPip1", transition); mRootWindowContainer.moveActivityToPinnedRootTaskAndRequestStart(r, "enterPictureInPictureMode"); } else if (getTransitionController().isCollecting() Loading @@ -3921,6 +3929,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { "auto-pip"); } r.mAutoEnteringPip = false; if (transition != null) { mChainTracker.end(); } } }; Loading