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

Commit 23c2c833 authored by Evan Rosky's avatar Evan Rosky Committed by Automerger Merge Worker
Browse files

Merge "Allow Recents transitions to collect in parallel" into udc-dev am: 966ee1fd

parents 6bf89062 966ee1fd
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -403,8 +403,11 @@ public class ActivityOptions extends ComponentOptions {
    private static final String KEY_SPLASH_SCREEN_STYLE =
            "android.activity.splashScreenStyle";

    /** See {@link #setTransientLaunch()}. */
    private static final String KEY_TRANSIENT_LAUNCH = "android.activity.transientLaunch";
    /**
     * See {@link #setTransientLaunch()}.
     * @hide
     */
    public static final String KEY_TRANSIENT_LAUNCH = "android.activity.transientLaunch";

    /** see {@link #makeLaunchIntoPip(PictureInPictureParams)}. */
    private static final String KEY_LAUNCH_INTO_PIP_PARAMS =
+24 −6
Original line number Diff line number Diff line
@@ -1183,6 +1183,12 @@
      "group": "WM_DEBUG_APP_TRANSITIONS",
      "at": "com\/android\/server\/wm\/AppTransitionController.java"
    },
    "-1005167552": {
      "message": "Playing #%d in parallel on track #%d",
      "level": "VERBOSE",
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "at": "com\/android\/server\/wm\/TransitionController.java"
    },
    "-1003678883": {
      "message": "Cleaning splash screen token=%s",
      "level": "VERBOSE",
@@ -1447,6 +1453,12 @@
      "group": "WM_DEBUG_TASKS",
      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
    },
    "-774908272": {
      "message": "Marking #%d animation as SYNC.",
      "level": "VERBOSE",
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "at": "com\/android\/server\/wm\/TransitionController.java"
    },
    "-771177730": {
      "message": "Removing focused app token:%s displayId=%d",
      "level": "VERBOSE",
@@ -1495,12 +1507,6 @@
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "-741766551": {
      "message": "Content Recording: Ignoring session on invalid virtual display",
      "level": "VERBOSE",
      "group": "WM_DEBUG_CONTENT_RECORDING",
      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
    },
    "-732715767": {
      "message": "Unable to retrieve window container to start recording for display %d",
      "level": "VERBOSE",
@@ -2017,6 +2023,12 @@
      "group": "WM_DEBUG_WALLPAPER",
      "at": "com\/android\/server\/wm\/WallpaperController.java"
    },
    "-266707683": {
      "message": "Moving #%d from collecting to waiting.",
      "level": "VERBOSE",
      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
      "at": "com\/android\/server\/wm\/TransitionController.java"
    },
    "-262984451": {
      "message": "Relaunch failed %s",
      "level": "INFO",
@@ -2089,6 +2101,12 @@
      "group": "WM_DEBUG_WINDOW_MOVEMENT",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-186693085": {
      "message": "Starting a Recents transition which can be parallel.",
      "level": "VERBOSE",
      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
      "at": "com\/android\/server\/wm\/Transition.java"
    },
    "-182877285": {
      "message": "Wallpaper layer changed: assigning layers + relayout",
      "level": "VERBOSE",
+30 −2
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_TASK_LAUNCHING_BEHIND;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static android.window.TransitionInfo.FLAG_WILL_IME_SHOWN;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_PENDING_INTENT;

import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
@@ -65,12 +66,14 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.IApplicationThread;
import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
@@ -85,6 +88,7 @@ import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.ScreenCapture;
import android.window.TransitionInfo;
import android.window.WindowContainerTransaction;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
@@ -185,7 +189,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
    final ArraySet<WindowContainer> mParticipants = new ArraySet<>();

    /** The final animation targets derived from participants after promotion. */
    private ArrayList<ChangeInfo> mTargets;
    ArrayList<ChangeInfo> mTargets;

    /** The displays that this transition is running on. */
    private final ArrayList<DisplayContent> mTargetDisplays = new ArrayList<>();
@@ -271,9 +275,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
    /** Any 2 transitions of this type can run in parallel with each other. Used for testing. */
    static final int PARALLEL_TYPE_MUTUAL = 1;

    /** This is a recents transition. */
    static final int PARALLEL_TYPE_RECENTS = 2;


    @IntDef(prefix = { "PARALLEL_TYPE_" }, value = {
            PARALLEL_TYPE_NONE,
            PARALLEL_TYPE_MUTUAL
            PARALLEL_TYPE_MUTUAL,
            PARALLEL_TYPE_RECENTS
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface ParallelType {}
@@ -328,6 +337,21 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        mFlags |= flag;
    }

    void calcParallelCollectType(WindowContainerTransaction wct) {
        for (int i = 0; i < wct.getHierarchyOps().size(); ++i) {
            final WindowContainerTransaction.HierarchyOp hop = wct.getHierarchyOps().get(i);
            if (hop.getType() != HIERARCHY_OP_TYPE_PENDING_INTENT) continue;
            final Bundle b = hop.getLaunchOptions();
            if (b == null || b.isEmpty()) continue;
            final boolean transientLaunch = b.getBoolean(ActivityOptions.KEY_TRANSIENT_LAUNCH);
            if (transientLaunch) {
                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                        "Starting a Recents transition which can be parallel.");
                mParallelCollectType = PARALLEL_TYPE_RECENTS;
            }
        }
    }

    /** Records an activity as transient-launch. This activity must be already collected. */
    void setTransientLaunch(@NonNull ActivityRecord activity, @Nullable Task restoreBelow) {
        if (mTransientLaunches == null) {
@@ -380,6 +404,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        return false;
    }

    boolean hasTransientLaunch() {
        return mTransientLaunches != null && !mTransientLaunches.isEmpty();
    }

    boolean isTransientLaunch(@NonNull ActivityRecord activity) {
        return mTransientLaunches != null && mTransientLaunches.containsKey(activity);
    }
+74 −1
Original line number Diff line number Diff line
@@ -879,6 +879,8 @@ class TransitionController {
            // If it's a legacy sync, then it needs to wait until there is no collecting transition.
            if (queued.mTransition == null) return;
            if (!canStartCollectingNow(queued.mTransition)) return;
            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS_MIN, "Moving #%d from collecting"
                    + " to waiting.", mCollectingTransition.getSyncId());
            mWaitingTransitions.add(mCollectingTransition);
            mCollectingTransition = null;
        } else if (mSyncEngine.hasActiveSync()) {
@@ -930,10 +932,37 @@ class TransitionController {
     * in {@link #getIsIndependent} later.
     */
    boolean getCanBeIndependent(Transition collecting, Transition queued) {
        // For tests
        if (queued.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL
                && collecting.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL) {
            return true;
        }
        // For recents
        if (queued.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
            if (collecting.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
                // Must serialize with itself.
                return false;
            }
            // allow this if `collecting` only has activities
            for (int i = 0; i < collecting.mParticipants.size(); ++i) {
                final WindowContainer wc = collecting.mParticipants.valueAt(i);
                final ActivityRecord ar = wc.asActivityRecord();
                if (ar == null && wc.asWindowState() == null && wc.asWindowToken() == null) {
                    // Is task or above, so can't be independent
                    return false;
                }
                if (ar != null && ar.isActivityTypeHomeOrRecents()) {
                    // It's a recents or home type, so it conflicts.
                    return false;
                }
            }
            return true;
        } else if (collecting.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
            // We can collect simultaneously with recents if it is populated. This is because
            // we know that recents will not collect/trampoline any more stuff. If anything in the
            // queued transition overlaps, it will end up just waiting in sync-queue anyways.
            return true;
        }
        return false;
    }

@@ -942,12 +971,48 @@ class TransitionController {
     * `running` is playing based on its current state.
     */
    static boolean getIsIndependent(Transition running, Transition incoming) {
        // For tests
        if (running.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL
                && incoming.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL) {
            return true;
        }
        // For now there's only one mutually-independent pair: an all activity-level transition and
        // a transient-launch where none of the activities are part of the transient-launch task,
        // so the following logic is hard-coded specifically for this.
        // Also, we currently restrict valid transient-launches to just recents.
        final Transition recents;
        final Transition other;
        if (running.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS
                && running.hasTransientLaunch()) {
            if (incoming.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
                // Recents can't be independent from itself.
                return false;
            }
            recents = running;
            other = incoming;
        } else if (incoming.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS
                && incoming.hasTransientLaunch()) {
            recents = incoming;
            other = running;
        } else {
            return false;
        }
        // Check against *targets* because that is the post-promotion set of containers that are
        // actually animating.
        for (int i = 0; i < other.mTargets.size(); ++i) {
            final WindowContainer wc = other.mTargets.get(i).mContainer;
            final ActivityRecord ar = wc.asActivityRecord();
            if (ar == null && wc.asWindowState() == null && wc.asWindowToken() == null) {
                // Is task or above, so for now don't let them be independent.
                return false;
            }
            if (ar != null && recents.isTransientLaunch(ar)) {
                // Change overlaps with recents, so serialize.
                return false;
            }
        }
        return true;
    }

    void assignTrack(Transition transition, TransitionInfo info) {
        int track = -1;
@@ -970,9 +1035,15 @@ class TransitionController {
        if (track < 0) {
            // Didn't overlap with anything, so give it its own track
            track = mTrackCount;
            if (track > 0) {
                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Playing #%d in parallel on "
                        + "track #%d", transition.getSyncId(), track);
            }
        }
        if (sync) {
            info.setFlags(info.getFlags() | TransitionInfo.FLAG_SYNC);
            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Marking #%d animation as SYNC.",
                    transition.getSyncId());
        }
        transition.mAnimationTrack = track;
        info.setTrack(track);
@@ -1145,6 +1216,8 @@ class TransitionController {
                // Check if we can run in parallel here.
                if (canStartCollectingNow(transit)) {
                    // start running in parallel.
                    ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS_MIN, "Moving #%d from"
                            + " collecting to waiting.", mCollectingTransition.getSyncId());
                    mWaitingTransitions.add(mCollectingTransition);
                    mCollectingTransition = null;
                    moveToCollecting(transit);
+1 −0
Original line number Diff line number Diff line
@@ -299,6 +299,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                    final boolean needsSetReady = t != null;
                    final Transition nextTransition = new Transition(type, 0 /* flags */,
                            mTransitionController, mService.mWindowManager.mSyncEngine);
                    nextTransition.calcParallelCollectType(wct);
                    mTransitionController.startCollectOrQueue(nextTransition,
                            (deferred) -> {
                                nextTransition.start();