Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ef534f5 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Track transition creation overlap" into main

parents ed87d3ee d09fe004
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -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()) {
@@ -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.
@@ -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;
@@ -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
+15 −3
Original line number Diff line number Diff line
@@ -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) {
@@ -880,6 +884,7 @@ class ActivityClientController extends IActivityClientController.Stub {
                        transition.abort();
                    }
                }
                mService.mChainTracker.end();
                return changed;
            }
        } finally {
@@ -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) {
@@ -927,6 +936,7 @@ class ActivityClientController extends IActivityClientController.Stub {
                        transition.abort();
                    }
                }
                mService.mChainTracker.end();
                return changed;
            }
        } finally {
@@ -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,
+19 −12
Original line number Diff line number Diff line
@@ -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);
@@ -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.
@@ -3706,6 +3709,7 @@ final class ActivityRecord extends WindowToken {
            return FINISH_RESULT_REQUESTED;
        } finally {
            mAtmService.continueWindowLayout();
            mAtmService.mChainTracker.endPartial();
        }
    }

@@ -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) {
@@ -4311,6 +4314,7 @@ final class ActivityRecord extends WindowToken {
            }
            removeFromHistory("appDied");
        }
        mAtmService.mChainTracker.end();
    }

    @Override
@@ -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();
+14 −9
Original line number Diff line number Diff line
@@ -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;
+15 −4
Original line number Diff line number Diff line
@@ -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 */);
@@ -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();
@@ -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 {
@@ -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;
        }
@@ -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()
@@ -3921,6 +3929,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                            "auto-pip");
                }
                r.mAutoEnteringPip = false;
                if (transition != null) {
                    mChainTracker.end();
                }
            }
        };

Loading