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

Commit 7fc8d28d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Generalize change transition into WindowContainer"

parents 74f681ee e55b9e0f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -697,6 +697,12 @@
      "group": "WM_DEBUG_FOCUS_LIGHT",
      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
    },
    "-668956537": {
      "message": "  THUMBNAIL %s: CREATE",
      "level": "INFO",
      "group": "WM_SHOW_TRANSACTIONS",
      "at": "com\/android\/server\/wm\/SurfaceFreezer.java"
    },
    "-666510420": {
      "message": "With display frozen, orientationChangeComplete=%b",
      "level": "VERBOSE",
+9 −8
Original line number Diff line number Diff line
@@ -275,8 +275,9 @@ class ActivityMetricsLogger {
        }

        /** @return {@code true} if the activity matches a launched activity in this transition. */
        boolean contains(ActivityRecord r) {
            return r == mLastLaunchedActivity || mPendingDrawActivities.contains(r);
        boolean contains(WindowContainer wc) {
            final ActivityRecord r = AppTransitionController.getAppFromContainer(wc);
            return r != null && (r == mLastLaunchedActivity || mPendingDrawActivities.contains(r));
        }

        /** Called when the activity is drawn or won't be drawn. */
@@ -435,10 +436,10 @@ class ActivityMetricsLogger {

    /** @return Non-null {@link TransitionInfo} if the activity is found in an active transition. */
    @Nullable
    private TransitionInfo getActiveTransitionInfo(ActivityRecord r) {
    private TransitionInfo getActiveTransitionInfo(WindowContainer wc) {
        for (int i = mTransitionInfoList.size() - 1; i >= 0; i--) {
            final TransitionInfo info = mTransitionInfoList.get(i);
            if (info.contains(r)) {
            if (info.contains(wc)) {
                return info;
            }
        }
@@ -623,19 +624,19 @@ class ActivityMetricsLogger {
     * @param activityToReason A map from activity to a reason integer, which must be on of
     *                         ActivityTaskManagerInternal.APP_TRANSITION_* reasons.
     */
    void notifyTransitionStarting(ArrayMap<ActivityRecord, Integer> activityToReason) {
    void notifyTransitionStarting(ArrayMap<WindowContainer, Integer> activityToReason) {
        if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");

        final long timestampNs = SystemClock.elapsedRealtimeNanos();
        for (int index = activityToReason.size() - 1; index >= 0; index--) {
            final ActivityRecord r = activityToReason.keyAt(index);
            final TransitionInfo info = getActiveTransitionInfo(r);
            final WindowContainer wc = activityToReason.keyAt(index);
            final TransitionInfo info = getActiveTransitionInfo(wc);
            if (info == null || info.mLoggedTransitionStarting) {
                // Ignore any subsequent notifyTransitionStarting.
                continue;
            }
            if (DEBUG_METRICS) {
                Slog.i(TAG, "notifyTransitionStarting activity=" + r + " info=" + info);
                Slog.i(TAG, "notifyTransitionStarting activity=" + wc + " info=" + info);
            }

            info.mCurrentTransitionDelayMs = info.calculateDelay(timestampNs);
+20 −148
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.activityTypeToString;
@@ -106,7 +105,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_UNSET;
@@ -284,7 +282,6 @@ import android.view.DisplayInfo;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IApplicationToken;
import android.view.InputApplicationHandle;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
@@ -577,12 +574,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     */
    private boolean mCurrentLaunchCanTurnScreenOn = true;

    /**
     * This leash is used to "freeze" the app surface in place after the state change, but before
     * the animation is ready to start.
     */
    private SurfaceControl mTransitChangeLeash = null;

    /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
    private boolean mLastSurfaceShowing = true;

@@ -1329,15 +1320,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            mDisplayContent.executeAppTransition();
        }

        if (prevDc.mChangingApps.remove(this)) {
            // This gets called *after* the ActivityRecord has been reparented to the new display.
            // That reparenting resulted in this window changing modes (eg. FREEFORM -> FULLSCREEN),
            // so this token is now "frozen" while waiting for the animation to start on prevDc
            // (which will be cancelled since the window is no-longer a child). However, since this
            // is no longer a child of prevDc, this won't be notified of the cancelled animation,
            // so we need to cancel the change transition here.
            clearChangeLeash(getPendingTransaction(), true /* cancel */);
        }
        prevDc.mClosingApps.remove(this);

        if (prevDc.mFocusedApp == this) {
@@ -3092,7 +3074,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        commitVisibility(false /* visible */, true /* performLayout */);

        getDisplayContent().mOpeningApps.remove(this);
        getDisplayContent().mChangingApps.remove(this);
        getDisplayContent().mChangingContainers.remove(this);
        getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
        mWmService.mTaskSnapshotController.onAppRemoved(this);
        mStackSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this);
@@ -4002,13 +3984,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                appToken, visible, appTransition, isVisible(), mVisibleRequested,
                Debug.getCallers(6));

        onChildVisibilityRequested(visible);

        final DisplayContent displayContent = getDisplayContent();
        displayContent.mOpeningApps.remove(this);
        displayContent.mClosingApps.remove(this);
        if (isInChangeTransition()) {
            clearChangeLeash(getPendingTransaction(), true /* cancel */);
        }
        displayContent.mChangingApps.remove(this);
        waitingToShow = false;
        mVisibleRequested = visible;
        mLastDeferHidingClient = deferHidingClient;
@@ -5812,11 +5792,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
    }

    @Override
    boolean isChangingAppTransition() {
        return task != null ? task.isChangingAppTransition() : super.isChangingAppTransition();
    }

    /**
     * Creates a layer to apply crop to an animation.
     */
@@ -5837,84 +5812,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                this, endDeferFinishCallback);
    }

    private boolean shouldStartChangeTransition(int prevWinMode, int newWinMode) {
        if (mWmService.mDisableTransitionAnimation
                || !isVisible()
                || getDisplayContent().mAppTransition.isTransitionSet()
                || getSurfaceControl() == null) {
            return false;
        }
        // Only do an animation into and out-of freeform mode for now. Other mode
        // transition animations are currently handled by system-ui.
        return (prevWinMode == WINDOWING_MODE_FREEFORM) != (newWinMode == WINDOWING_MODE_FREEFORM);
    }

    @Override
    boolean isWaitingForTransitionStart() {
        final DisplayContent dc = getDisplayContent();
        return dc != null && dc.mAppTransition.isTransitionSet()
                && (dc.mOpeningApps.contains(this)
                || dc.mClosingApps.contains(this)
                || dc.mChangingApps.contains(this));
    }

    /**
     * Initializes a change transition. Because the app is visible already, there is a small period
     * of time where the user can see the app content/window update before the transition starts.
     * To prevent this, we immediately take a snapshot and place the app/snapshot into a leash which
     * "freezes" the location/crop until the transition starts.
     * <p>
     * Here's a walk-through of the process:
     * 1. Create a temporary leash ("interim-change-leash") and reparent the app to it.
     * 2. Set the temporary leash's position/crop to the current state.
     * 3. Create a snapshot and place that at the top of the leash to cover up content changes.
     * 4. Once the transition is ready, it will reparent the app to the animation leash.
     * 5. Detach the interim-change-leash.
     */
    private void initializeChangeTransition(Rect startBounds) {
        mDisplayContent.prepareAppTransition(TRANSIT_TASK_CHANGE_WINDOWING_MODE,
                false /* alwaysKeepCurrent */, 0, false /* forceOverride */);
        mDisplayContent.mChangingApps.add(this);
        mTransitStartRect.set(startBounds);

        final SurfaceControl.Builder builder = makeAnimationLeash()
                .setParent(getAnimationLeashParent())
                .setName(getSurfaceControl() + " - interim-change-leash");
        mTransitChangeLeash = builder.build();
        Transaction t = getPendingTransaction();
        t.setWindowCrop(mTransitChangeLeash, startBounds.width(), startBounds.height());
        t.setPosition(mTransitChangeLeash, startBounds.left, startBounds.top);
        t.show(mTransitChangeLeash);
        t.reparent(getSurfaceControl(), mTransitChangeLeash);
        onAnimationLeashCreated(t, mTransitChangeLeash);

        // Skip creating snapshot if this transition is controlled by a remote animator which
        // doesn't need it.
        ArraySet<Integer> activityTypes = new ArraySet<>();
        activityTypes.add(getActivityType());
        RemoteAnimationAdapter adapter =
                mDisplayContent.mAppTransitionController.getRemoteAnimationOverride(
                        this, TRANSIT_TASK_CHANGE_WINDOWING_MODE, activityTypes);
        if (adapter != null && !adapter.getChangeNeedsSnapshot()) {
            return;
        }

        if (mThumbnail == null && task != null && !hasCommittedReparentToAnimationLeash()) {
            SurfaceControl.ScreenshotGraphicBuffer snapshot =
                    mWmService.mTaskSnapshotController.createTaskSnapshot(
                            task, 1 /* scaleFraction */);
            if (snapshot != null) {
                mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory, t, this,
                        snapshot.getGraphicBuffer(), true /* relative */);
            }
        }
                || dc.mChangingContainers.contains(this));
    }

    @Override
    public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
    private int getAnimationLayer() {
        // The leash is parented to the animation layer. We need to preserve the z-order by using
        // the prefix order index, but we boost if necessary.
        int layer = 0;
        int layer;
        if (!inPinnedWindowingMode()) {
            layer = getPrefixOrderIndex();
        } else {
@@ -5927,21 +5837,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (mNeedsZBoost) {
            layer += Z_BOOST_BASE;
        }
        if (!mNeedsAnimationBoundsLayer) {
            t.setLayer(leash, layer);
        return layer;
    }

        final DisplayContent dc = getDisplayContent();
        dc.assignStackOrdering();

        if (leash == mTransitChangeLeash) {
            // This is a temporary state so skip any animation notifications
            return;
        } else if (mTransitChangeLeash != null) {
            // unparent mTransitChangeLeash for clean-up
            clearChangeLeash(t, false /* cancel */);
    @Override
    public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
        t.setLayer(leash, getAnimationLayer());
        getDisplayContent().assignStackOrdering();
    }

    @Override
    public void onLeashAnimationStarting(Transaction t, SurfaceControl leash) {
        if (mAnimatingActivityRegistry != null) {
            mAnimatingActivityRegistry.notifyStarting(this);
        }
@@ -5969,7 +5875,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                // surface size has already same as the animating container.
                t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
            }
            t.setLayer(mAnimationBoundsLayer, layer);
            t.setLayer(leash, 0);
            t.setLayer(mAnimationBoundsLayer, getAnimationLayer());

            // Reparent leash to animation bounds layer.
            t.reparent(leash, mAnimationBoundsLayer);
@@ -6001,10 +5908,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return mLastSurfaceShowing;
    }

    boolean isInChangeTransition() {
        return mTransitChangeLeash != null || AppTransition.isChangeTransit(mTransit);
    }

    void attachThumbnailAnimation() {
        if (!isAnimating(PARENTS)) {
            return;
@@ -6141,31 +6044,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

    /**
     * @param cancel {@code true} if clearing the leash due to cancelling instead of transferring
     *                            to another leash.
     */
    private void clearChangeLeash(Transaction t, boolean cancel) {
        if (mTransitChangeLeash == null) {
            return;
        }
        if (cancel) {
            clearThumbnail();
            SurfaceControl sc = getSurfaceControl();
            SurfaceControl parentSc = getParentSurfaceControl();
            // Don't reparent if surface is getting destroyed
            if (parentSc != null && sc != null) {
                t.reparent(sc, getParentSurfaceControl());
            }
        }
        t.hide(mTransitChangeLeash);
        t.remove(mTransitChangeLeash);
        mTransitChangeLeash = null;
        if (cancel) {
            onAnimationLeashLost(t);
        }
    }

    void clearAnimatingFlags() {
        boolean wallpaperMightChange = false;
        for (int i = mChildren.size() - 1; i >= 0; i--) {
@@ -6181,7 +6059,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    void cancelAnimation() {
        cancelAnimationOnly();
        clearThumbnail();
        clearChangeLeash(getPendingTransaction(), true /* cancel */);
        mSurfaceFreezer.unfreeze(getPendingTransaction());
    }

    /**
@@ -6226,6 +6104,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        mRemoteAnimationDefinition = null;
    }

    @Override
    RemoteAnimationDefinition getRemoteAnimationDefinition() {
        return mRemoteAnimationDefinition;
    }
@@ -6686,8 +6565,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                return;
            }
        }
        final int prevWinMode = getWindowingMode();
        mTmpPrevBounds.set(getBounds());
        super.onConfigurationChanged(newParentConfig);

        if (shouldUseSizeCompatMode()) {
@@ -6712,12 +6589,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            }
        }

        final int newWinMode = getWindowingMode();
        if ((prevWinMode != newWinMode) && (mDisplayContent != null)
                && shouldStartChangeTransition(prevWinMode, newWinMode)) {
            initializeChangeTransition(mTmpPrevBounds);
        }

        // Configuration's equality doesn't consider seq so if only seq number changes in resolved
        // override configuration. Therefore ConfigurationContainer doesn't change merged override
        // configuration, but it's used to push configuration changes so explicitly update that.
@@ -7612,6 +7483,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
    }

    @Override
    void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
        proto.write(HASH_CODE, System.identityHashCode(this));
+2 −2
Original line number Diff line number Diff line
@@ -2308,14 +2308,14 @@ public class AppTransition implements Dump {
            }
            notifyAppTransitionTimeoutLocked();
            if (isTransitionSet() || !dc.mOpeningApps.isEmpty() || !dc.mClosingApps.isEmpty()
                    || !dc.mChangingApps.isEmpty()) {
                    || !dc.mChangingContainers.isEmpty()) {
                ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
                            "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b "
                                    + "mOpeningApps.size()=%d mClosingApps.size()=%d "
                                    + "mChangingApps.size()=%d",
                            dc.getDisplayId(), dc.mAppTransition.isTransitionSet(),
                            dc.mOpeningApps.size(), dc.mClosingApps.size(),
                            dc.mChangingApps.size());
                            dc.mChangingContainers.size());

                setTimeout();
                mService.mWindowPlacerLocked.performSurfacePlacement();
+51 −43

File changed.

Preview size limit exceeded, changes collapsed.

Loading