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

Commit 6173c266 authored by Evan Rosky's avatar Evan Rosky
Browse files

Some fixes to shell transitions lifecycle handling

Added a remote transitionfilter for container ordering. This way
launcher animation won't engage if it is appearing behind a
translucent task.

Modify commitVisibility to properly update client visibility
when shell transitions are enabled.

Fixed issue where activity start was deferring sync-engine
readiness even for "delivered-to-top" or cancelled activity
starts. This meant it would wait forever.

Hooked up the "enter animation complete" reporting to shell
transitions.

Removed interference by legacy freeform/maximize animation
logic (which was calling setReady at incorrect times).

Bug: 183993924
Test: atest ActivityLifecycleTests
Change-Id: I1138079b1ae05248cefa211e0597fd6723a8bbba
parent f01e33f1
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.window;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
@@ -33,6 +34,18 @@ import android.os.Parcelable;
 */
public final class TransitionFilter implements Parcelable {

    /** The associated requirement doesn't care about the z-order. */
    public static final int CONTAINER_ORDER_ANY = 0;
    /** The associated requirement only matches the top-most (z-order) container. */
    public static final int CONTAINER_ORDER_TOP = 1;

    /** @hide */
    @IntDef(prefix = { "CONTAINER_ORDER_" }, value = {
            CONTAINER_ORDER_ANY,
            CONTAINER_ORDER_TOP,
    })
    public @interface ContainerOrder {}

    /**
     * When non-null: this is a list of transition types that this filter applies to. This filter
     * will fail for transitions that aren't one of these types.
@@ -126,6 +139,7 @@ public final class TransitionFilter implements Parcelable {
    public static final class Requirement implements Parcelable {
        public int mActivityType = ACTIVITY_TYPE_UNDEFINED;
        public int[] mModes = null;
        public @ContainerOrder int mOrder = CONTAINER_ORDER_ANY;

        public Requirement() {
        }
@@ -133,6 +147,7 @@ public final class TransitionFilter implements Parcelable {
        private Requirement(Parcel in) {
            mActivityType = in.readInt();
            mModes = in.createIntArray();
            mOrder = in.readInt();
        }

        /** Go through changes and find if at-least one change matches this filter */
@@ -143,6 +158,9 @@ public final class TransitionFilter implements Parcelable {
                    // Only look at independent animating windows.
                    continue;
                }
                if (mOrder == CONTAINER_ORDER_TOP && i > 0) {
                    continue;
                }
                if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
                    if (change.getTaskInfo() == null
                            || change.getTaskInfo().getActivityType() != mActivityType) {
@@ -166,7 +184,7 @@ public final class TransitionFilter implements Parcelable {

        /** Check if the request matches this filter. It may generate false positives */
        boolean matches(@NonNull TransitionRequestInfo request) {
            // Can't check modes since the transition hasn't been built at this point.
            // Can't check modes/order since the transition hasn't been built at this point.
            if (mActivityType == ACTIVITY_TYPE_UNDEFINED) return true;
            return request.getTriggerTask() != null
                    && request.getTriggerTask().getActivityType() == mActivityType;
@@ -177,6 +195,7 @@ public final class TransitionFilter implements Parcelable {
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeInt(mActivityType);
            dest.writeIntArray(mModes);
            dest.writeInt(mOrder);
        }

        @NonNull
@@ -209,7 +228,17 @@ public final class TransitionFilter implements Parcelable {
                    out.append((i == 0 ? "" : ",") + TransitionInfo.modeToString(mModes[i]));
                }
            }
            return out.append("]}").toString();
            out.append("]").toString();
            out.append(" order=" + containerOrderToString(mOrder));
            return out.toString();
        }
    }

    private static String containerOrderToString(int order) {
        switch (order) {
            case CONTAINER_ORDER_ANY: return "ANY";
            case CONTAINER_ORDER_TOP: return "TOP";
        }
        return "UNKNOWN(" + order + ")";
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -17,10 +17,12 @@
package com.android.systemui.shared.system;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionFilter.CONTAINER_ORDER_TOP;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -163,9 +165,13 @@ public class RemoteTransitionCompat implements Parcelable {
            mFilter = new TransitionFilter();
        }
        mFilter.mRequirements =
                new TransitionFilter.Requirement[]{new TransitionFilter.Requirement()};
                new TransitionFilter.Requirement[]{new TransitionFilter.Requirement(),
                        new TransitionFilter.Requirement()};
        mFilter.mRequirements[0].mActivityType = ACTIVITY_TYPE_HOME;
        mFilter.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
        mFilter.mRequirements[0].mOrder = CONTAINER_ORDER_TOP;
        mFilter.mRequirements[1].mActivityType = ACTIVITY_TYPE_STANDARD;
        mFilter.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
    }

    /**
+5 −2
Original line number Diff line number Diff line
@@ -4817,9 +4817,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     *                this has become invisible.
     */
    private void postApplyAnimation(boolean visible) {
        final boolean usingShellTransitions =
                mAtmService.getTransitionController().getTransitionPlayer() != null;
        final boolean delayed = isAnimating(PARENTS | CHILDREN,
                ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_WINDOW_ANIMATION);
        if (!delayed) {
        if (!delayed && !usingShellTransitions) {
            // We aren't delayed anything, but exiting windows rely on the animation finished
            // callback being called in case the ActivityRecord was pretending to be delayed,
            // which we might have done because we were in closing/opening apps list.
@@ -4838,7 +4840,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // updated.
        // If we're becoming invisible, update the client visibility if we are not running an
        // animation. Otherwise, we'll update client visibility in onAnimationFinished.
        if (visible || !isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION)) {
        if (visible || !isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION)
                || usingShellTransitions) {
            setClientVisible(visible);
        }

+3 −2
Original line number Diff line number Diff line
@@ -1586,7 +1586,8 @@ class ActivityStarter {
                        statusBar.collapsePanels();
                    }
                }
                if (result == START_SUCCESS || result == START_TASK_TO_FRONT) {
                final boolean started = result == START_SUCCESS || result == START_TASK_TO_FRONT;
                if (started) {
                    // The activity is started new rather than just brought forward, so record
                    // it as an existence change.
                    mService.getTransitionController().collectExistenceChange(r);
@@ -1594,7 +1595,7 @@ class ActivityStarter {
                if (newTransition != null) {
                    mService.getTransitionController().requestStartTransition(newTransition,
                            mTargetTask, remoteTransition);
                } else {
                } else if (started) {
                    // Make the collecting transition wait until this request is ready.
                    mService.getTransitionController().setReady(false);
                }
+24 −12
Original line number Diff line number Diff line
@@ -297,21 +297,27 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        }

        // Commit all going-invisible containers
        boolean activitiesWentInvisible = false;
        for (int i = 0; i < mParticipants.size(); ++i) {
            final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
            if (ar != null && !ar.isVisibleRequested()) {
            if (ar != null) {
                if (!ar.isVisibleRequested()) {
                    // If activity is capable of entering PiP, give it a chance to enter it now.
                    if (ar.getDeferHidingClient() && ar.getTask() != null) {
                        mController.mAtm.mTaskSupervisor.mUserLeaving = true;
                    ar.getTaskFragment().startPausing(false /* uiSleeping */, null /* resuming */,
                            "finishTransition");
                        ar.getTaskFragment().startPausing(false /* uiSleeping */,
                                null /* resuming */, "finishTransition");
                        mController.mAtm.mTaskSupervisor.mUserLeaving = false;
                    }
                    ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                            "  Commit activity becoming invisible: %s", ar);
                    ar.commitVisibility(false /* visible */, false /* performLayout */);
                    activitiesWentInvisible = true;
                }
                if (mChanges.get(ar).mVisible != ar.isVisibleRequested()) {
                    // Legacy dispatch relies on this (for now).
                    ar.mEnteringAnimation = ar.isVisibleRequested();
                }
            if (ar != null) {
                mController.dispatchLegacyAppTransitionFinished(ar);
            }
            final WallpaperWindowToken wt = mParticipants.valueAt(i).asWallpaperToken();
@@ -321,6 +327,12 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
                wt.commitVisibility(false /* visible */);
            }
        }
        if (activitiesWentInvisible) {
            // Always schedule stop processing when transition finishes because activities don't
            // stop while they are in a transition thus their stop could still be pending.
            mController.mAtm.mTaskSupervisor
                    .scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
        }

        legacyRestoreNavigationBarFromApp();
    }
Loading