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

Commit 9f26aed8 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Remove SurfaceFreezer

Since shell transition, now it is done by
Transition.ScreenshotFreezer.

Bug: 365884835
Flag: EXEMPT remove outdated code
Test: atest WindowContainerTests
Change-Id: I240c501af1e1293be7cc0f9a6d817b897928b2d8
parent 71378c18
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -5607,7 +5607,6 @@ final class ActivityRecord extends WindowToken {
        }
        }


        mAtmService.mBackNavigationController.onAppVisibilityChanged(this, visible);
        mAtmService.mBackNavigationController.onAppVisibilityChanged(this, visible);
        onChildVisibilityRequested(visible);


        final DisplayContent displayContent = getDisplayContent();
        final DisplayContent displayContent = getDisplayContent();
        displayContent.mOpeningApps.remove(this);
        displayContent.mOpeningApps.remove(this);
+0 −12
Original line number Original line Diff line number Diff line
@@ -80,7 +80,6 @@ import android.os.Trace;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Pair;
import android.view.Display;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;
import android.view.WindowManager;
@@ -252,7 +251,6 @@ public class AppTransitionController {
        // Check if there is any override
        // Check if there is any override
        if (!overrideWithTaskFragmentRemoteAnimation(transit, activityTypes)) {
        if (!overrideWithTaskFragmentRemoteAnimation(transit, activityTypes)) {
            // Unfreeze the windows that were previously frozen for TaskFragment animation.
            // Unfreeze the windows that were previously frozen for TaskFragment animation.
            unfreezeEmbeddedChangingWindows();
            overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
            overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes);
        }
        }


@@ -545,16 +543,6 @@ public class AppTransitionController {
                : null;
                : null;
    }
    }


    private void unfreezeEmbeddedChangingWindows() {
        final ArraySet<WindowContainer> changingContainers = mDisplayContent.mChangingContainers;
        for (int i = changingContainers.size() - 1; i >= 0; i--) {
            final WindowContainer wc = changingContainers.valueAt(i);
            if (wc.isEmbedded()) {
                wc.mSurfaceFreezer.unfreeze(wc.getSyncTransaction());
            }
        }
    }

    private boolean transitionMayContainNonAppWindows(@TransitionOldType int transit) {
    private boolean transitionMayContainNonAppWindows(@TransitionOldType int transit) {
        // We don't want to have the client to animate any non-app windows.
        // We don't want to have the client to animate any non-app windows.
        // Having {@code transit} of those types doesn't mean it will contain non-app windows, but
        // Having {@code transit} of those types doesn't mean it will contain non-app windows, but
+3 −25
Original line number Original line Diff line number Diff line
@@ -60,8 +60,6 @@ public class SurfaceAnimator {
    @VisibleForTesting
    @VisibleForTesting
    SurfaceControl mLeash;
    SurfaceControl mLeash;
    @VisibleForTesting
    @VisibleForTesting
    SurfaceFreezer.Snapshot mSnapshot;
    @VisibleForTesting
    final Animatable mAnimatable;
    final Animatable mAnimatable;
    @VisibleForTesting
    @VisibleForTesting
    final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
    final OnAnimationFinishedCallback mInnerAnimationFinishedCallback;
@@ -165,7 +163,7 @@ public class SurfaceAnimator {
            @AnimationType int type,
            @AnimationType int type,
            @Nullable OnAnimationFinishedCallback animationFinishedCallback,
            @Nullable OnAnimationFinishedCallback animationFinishedCallback,
            @Nullable Runnable animationCancelledCallback,
            @Nullable Runnable animationCancelledCallback,
            @Nullable AnimationAdapter snapshotAnim, @Nullable SurfaceFreezer freezer) {
            @Nullable AnimationAdapter snapshotAnim) {
        cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
        cancelAnimation(t, true /* restarting */, true /* forwardCancel */);
        mAnimation = anim;
        mAnimation = anim;
        mAnimationType = type;
        mAnimationType = type;
@@ -177,7 +175,6 @@ public class SurfaceAnimator {
            cancelAnimation();
            cancelAnimation();
            return;
            return;
        }
        }
        mLeash = freezer != null ? freezer.takeLeashForAnimation() : null;
        if (mLeash == null) {
        if (mLeash == null) {
            mLeash = createAnimationLeash(mAnimatable, surface, t, type,
            mLeash = createAnimationLeash(mAnimatable, surface, t, type,
                    mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
                    mAnimatable.getSurfaceWidth(), mAnimatable.getSurfaceHeight(), 0 /* x */,
@@ -192,21 +189,13 @@ public class SurfaceAnimator {
            mAnimation.dump(pw, "");
            mAnimation.dump(pw, "");
            ProtoLog.d(WM_DEBUG_ANIM, "Animation start for %s, anim=%s", mAnimatable, sw);
            ProtoLog.d(WM_DEBUG_ANIM, "Animation start for %s, anim=%s", mAnimatable, sw);
        }
        }
        if (snapshotAnim != null) {
            mSnapshot = freezer.takeSnapshotForAnimation();
            if (mSnapshot == null) {
                Slog.e(TAG, "No snapshot target to start animation on for " + mAnimatable);
                return;
            }
            mSnapshot.startAnimation(t, snapshotAnim, type);
        }
        setAnimatorPendingState(t);
        setAnimatorPendingState(t);
    }
    }


    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
            @AnimationType int type) {
            @AnimationType int type) {
        startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */,
        startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */,
                null /* animationCancelledCallback */, null /* snapshotAnim */, null /* freezer */);
                null /* animationCancelledCallback */, null /* snapshotAnim */);
    }
    }


    /** Indicates that there are surface operations in the pending transaction. */
    /** Indicates that there are surface operations in the pending transaction. */
@@ -317,7 +306,6 @@ public class SurfaceAnimator {
        final OnAnimationFinishedCallback animationFinishedCallback =
        final OnAnimationFinishedCallback animationFinishedCallback =
                mSurfaceAnimationFinishedCallback;
                mSurfaceAnimationFinishedCallback;
        final Runnable animationCancelledCallback = mAnimationCancelledCallback;
        final Runnable animationCancelledCallback = mAnimationCancelledCallback;
        final SurfaceFreezer.Snapshot snapshot = mSnapshot;
        reset(t, false);
        reset(t, false);
        if (animation != null) {
        if (animation != null) {
            if (forwardCancel) {
            if (forwardCancel) {
@@ -337,9 +325,6 @@ public class SurfaceAnimator {
        }
        }


        if (forwardCancel) {
        if (forwardCancel) {
            if (snapshot != null) {
                snapshot.cancelAnimation(t, false /* restarting */);
            }
            if (leash != null) {
            if (leash != null) {
                t.remove(leash);
                t.remove(leash);
                mService.scheduleAnimationLocked();
                mService.scheduleAnimationLocked();
@@ -352,12 +337,6 @@ public class SurfaceAnimator {
        mAnimation = null;
        mAnimation = null;
        mSurfaceAnimationFinishedCallback = null;
        mSurfaceAnimationFinishedCallback = null;
        mAnimationType = ANIMATION_TYPE_NONE;
        mAnimationType = ANIMATION_TYPE_NONE;
        final SurfaceFreezer.Snapshot snapshot = mSnapshot;
        mSnapshot = null;
        if (snapshot != null) {
            // Reset the mSnapshot reference before calling the callback to prevent circular reset.
            snapshot.cancelAnimation(t, !destroyLeash);
        }
        if (mLeash == null) {
        if (mLeash == null) {
            return;
            return;
        }
        }
@@ -597,8 +576,7 @@ public class SurfaceAnimator {
        void commitPendingTransaction();
        void commitPendingTransaction();


        /**
        /**
         * Called when the animation leash is created. Note that this is also called by
         * Called when the animation leash is created.
         * {@link SurfaceFreezer}, so this doesn't mean we're about to start animating.
         *
         *
         * @param t The transaction to use to apply any necessary changes.
         * @param t The transaction to use to apply any necessary changes.
         * @param leash The leash that was created.
         * @param leash The leash that was created.
+0 −303
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm;

import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATION;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.util.Slog;
import android.view.SurfaceControl;
import android.window.ScreenCapture;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;

/**
 * This class handles "freezing" of an Animatable. The Animatable in question should implement
 * Freezable.
 *
 * The point of this is to enable WindowContainers to each be capable of freezing themselves.
 * Freezing means taking a snapshot and placing it above everything in the sub-hierarchy.
 * The "placing above" requires that a parent surface be inserted above the target surface so that
 * the target surface and the snapshot are siblings.
 *
 * The overall flow for a transition using this would be:
 * 1. Set transition and record animatable in mChangingApps
 * 2. Call {@link #freeze} to set-up the leashes and cover with a snapshot.
 * 3. When transition participants are ready, start SurfaceAnimator with this as a parameter
 * 4. SurfaceAnimator will then {@link #takeLeashForAnimation} instead of creating another leash.
 * 5. The animation system should eventually clean this up via {@link #unfreeze}.
 */
class SurfaceFreezer {

    private static final String TAG = "SurfaceFreezer";

    private final @NonNull Freezable mAnimatable;
    private final @NonNull WindowManagerService mWmService;
    @VisibleForTesting
    SurfaceControl mLeash;
    Snapshot mSnapshot = null;
    final Rect mFreezeBounds = new Rect();

    /**
     * @param animatable The object to animate.
     */
    SurfaceFreezer(@NonNull Freezable animatable, @NonNull WindowManagerService service) {
        mAnimatable = animatable;
        mWmService = service;
    }

    /**
     * Freeze the target surface. This is done by creating a leash (inserting a parent surface
     * above the target surface) and then taking a snapshot and placing it over the target surface.
     *
     * @param startBounds The original bounds (on screen) of the surface we are snapshotting.
     * @param relativePosition The related position of the snapshot surface to its parent.
     * @param freezeTarget The surface to take snapshot from. If {@code null}, we will take a
     *                     snapshot from the {@link #mAnimatable} surface.
     */
    void freeze(SurfaceControl.Transaction t, Rect startBounds, Point relativePosition,
            @Nullable SurfaceControl freezeTarget) {
        reset(t);
        mFreezeBounds.set(startBounds);

        mLeash = SurfaceAnimator.createAnimationLeash(mAnimatable, mAnimatable.getSurfaceControl(),
                t, ANIMATION_TYPE_SCREEN_ROTATION, startBounds.width(), startBounds.height(),
                relativePosition.x, relativePosition.y, false /* hidden */,
                mWmService.mTransactionFactory);
        mAnimatable.onAnimationLeashCreated(t, mLeash);

        freezeTarget = freezeTarget != null ? freezeTarget : mAnimatable.getFreezeSnapshotTarget();
        if (freezeTarget != null) {
            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer = createSnapshotBufferInner(
                    freezeTarget, startBounds);
            final HardwareBuffer buffer = screenshotBuffer == null ? null
                    : screenshotBuffer.getHardwareBuffer();
            if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
                // This can happen when display is not ready.
                Slog.w(TAG, "Failed to capture screenshot for " + mAnimatable);
                unfreeze(t);
                return;
            }
            mSnapshot = new Snapshot(t, screenshotBuffer, mLeash);
        }
    }

    /**
     * Used by {@link SurfaceAnimator}. This "transfers" the leash to be used for animation.
     * By transferring the leash, this will no longer try to clean-up the leash when finished.
     */
    SurfaceControl takeLeashForAnimation() {
        SurfaceControl out = mLeash;
        mLeash = null;
        return out;
    }

    /**
     * Used by {@link SurfaceAnimator}. This "transfers" the snapshot leash to be used for
     * animation. By transferring the leash, this will no longer try to clean-up the leash when
     * finished.
     */
    @Nullable
    Snapshot takeSnapshotForAnimation() {
        final Snapshot out = mSnapshot;
        mSnapshot = null;
        return out;
    }

    /**
     * Clean-up the snapshot and remove leash. If the leash was taken, this just cleans-up the
     * snapshot.
     */
    void unfreeze(SurfaceControl.Transaction t) {
        unfreezeInner(t);
        mAnimatable.onUnfrozen();
    }

    private void unfreezeInner(SurfaceControl.Transaction t) {
        if (mSnapshot != null) {
            mSnapshot.cancelAnimation(t, false /* restarting */);
            mSnapshot = null;
        }
        if (mLeash == null) {
            return;
        }
        SurfaceControl leash = mLeash;
        mLeash = null;
        final boolean scheduleAnim = SurfaceAnimator.removeLeash(t, mAnimatable, leash,
                true /* destroy */);
        if (scheduleAnim) {
            mWmService.scheduleAnimationLocked();
        }
    }

    /** Resets the snapshot before taking another one if the animation hasn't been started yet. */
    private void reset(SurfaceControl.Transaction t) {
        // Those would have been taken by the SurfaceAnimator if the animation has been started, so
        // we can remove the leash directly.
        // No need to reset the mAnimatable leash, as this is called before a new animation leash is
        // created, so another #onAnimationLeashCreated will be called.
        if (mSnapshot != null) {
            mSnapshot.destroy(t);
            mSnapshot = null;
        }
        if (mLeash != null) {
            t.remove(mLeash);
            mLeash = null;
        }
    }

    void setLayer(SurfaceControl.Transaction t, int layer) {
        if (mLeash != null) {
            t.setLayer(mLeash, layer);
        }
    }

    void setRelativeLayer(SurfaceControl.Transaction t, SurfaceControl relativeTo, int layer) {
        if (mLeash != null) {
            t.setRelativeLayer(mLeash, relativeTo, layer);
        }
    }

    boolean hasLeash() {
        return mLeash != null;
    }

    private static ScreenCapture.ScreenshotHardwareBuffer createSnapshotBuffer(
            @NonNull SurfaceControl target, @Nullable Rect bounds) {
        Rect cropBounds = null;
        if (bounds != null) {
            cropBounds = new Rect(bounds);
            cropBounds.offsetTo(0, 0);
        }
        ScreenCapture.LayerCaptureArgs captureArgs =
                new ScreenCapture.LayerCaptureArgs.Builder(target)
                        .setSourceCrop(cropBounds)
                        .setCaptureSecureLayers(true)
                        .setAllowProtected(true)
                        .build();
        return ScreenCapture.captureLayers(captureArgs);
    }

    @VisibleForTesting
    ScreenCapture.ScreenshotHardwareBuffer createSnapshotBufferInner(
            SurfaceControl target, Rect bounds) {
        return createSnapshotBuffer(target, bounds);
    }

    @VisibleForTesting
    GraphicBuffer createFromHardwareBufferInner(
            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer) {
        return GraphicBuffer.createFromHardwareBuffer(screenshotBuffer.getHardwareBuffer());
    }

    class Snapshot {
        private SurfaceControl mSurfaceControl;
        private AnimationAdapter mAnimation;

        /**
         * @param t Transaction to create the thumbnail in.
         * @param screenshotBuffer A thumbnail or placeholder for thumbnail to initialize with.
         */
        Snapshot(SurfaceControl.Transaction t,
                ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
            GraphicBuffer graphicBuffer = createFromHardwareBufferInner(screenshotBuffer);

            mSurfaceControl = mAnimatable.makeAnimationLeash()
                    .setName("snapshot anim: " + mAnimatable.toString())
                    .setFormat(PixelFormat.TRANSLUCENT)
                    .setParent(parent)
                    .setSecure(screenshotBuffer.containsSecureLayers())
                    .setCallsite("SurfaceFreezer.Snapshot")
                    .setBLASTLayer()
                    .build();

            ProtoLog.i(WM_SHOW_TRANSACTIONS, "  THUMBNAIL %s: CREATE", mSurfaceControl);

            t.setBuffer(mSurfaceControl, graphicBuffer);
            t.setColorSpace(mSurfaceControl, screenshotBuffer.getColorSpace());
            t.show(mSurfaceControl);

            // We parent the thumbnail to the container, and just place it on top of anything else
            // in the container.
            t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
        }

        void destroy(SurfaceControl.Transaction t) {
            if (mSurfaceControl == null) {
                return;
            }
            t.remove(mSurfaceControl);
            mSurfaceControl = null;
        }

        /**
         * Starts an animation.
         *
         * @param anim The object that bridges the controller, {@link SurfaceAnimator}, with the
         *             component responsible for running the animation. It runs the animation with
         *             {@link AnimationAdapter#startAnimation} once the hierarchy with
         *             the Leash has been set up.
         */
        void startAnimation(SurfaceControl.Transaction t, AnimationAdapter anim, int type) {
            cancelAnimation(t, true /* restarting */);
            mAnimation = anim;
            if (mSurfaceControl == null) {
                cancelAnimation(t, false /* restarting */);
                return;
            }
            mAnimation.startAnimation(mSurfaceControl, t, type, (typ, ani) -> { });
        }

        /**
         * Cancels the animation, and resets the leash.
         *
         * @param t The transaction to use for all cancelling surface operations.
         * @param restarting Whether we are restarting the animation.
         */
        void cancelAnimation(SurfaceControl.Transaction t, boolean restarting) {
            final SurfaceControl leash = mSurfaceControl;
            final AnimationAdapter animation = mAnimation;
            mAnimation = null;
            if (animation != null) {
                animation.onAnimationCancelled(leash);
            }
            if (!restarting) {
                destroy(t);
            }
        }
    }

    /** freezable */
    public interface Freezable extends SurfaceAnimator.Animatable {
        /**
         * @return The surface to take a snapshot of. If this returns {@code null}, no snapshot
         *         will be generated (but the rest of the freezing logic will still happen).
         */
        @Nullable SurfaceControl getFreezeSnapshotTarget();

        /** Called when the {@link #unfreeze(SurfaceControl.Transaction)} is called. */
        void onUnfrozen();
    }
}
+1 −29
Original line number Original line Diff line number Diff line
@@ -52,11 +52,9 @@ import static android.view.SurfaceControl.METADATA_TASK_ID;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -75,7 +73,6 @@ import static com.android.server.wm.ActivityRecord.TRANSFER_SPLASH_SCREEN_COPYIN
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CLEANUP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CLEANUP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
@@ -161,13 +158,11 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings;
import android.service.voice.IVoiceInteractionSession;
import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.util.Slog;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
import android.view.DisplayInfo;
import android.view.InsetsState;
import android.view.InsetsState;
import android.view.RemoteAnimationAdapter;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
import android.view.WindowInsets;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManager;
@@ -2344,32 +2339,9 @@ class Task extends TaskFragment {
        mLastSurfaceSize.set(width, height);
        mLastSurfaceSize.set(width, height);
    }
    }


    @VisibleForTesting
    Point getLastSurfaceSize() {
        return mLastSurfaceSize;
    }

    @VisibleForTesting
    @VisibleForTesting
    boolean isInChangeTransition() {
    boolean isInChangeTransition() {
        return mSurfaceFreezer.hasLeash() || AppTransition.isChangeTransitOld(mTransit);
        return AppTransition.isChangeTransitOld(mTransit);
    }

    @Override
    public SurfaceControl getFreezeSnapshotTarget() {
        if (!mDisplayContent.mAppTransition.containsTransitRequest(TRANSIT_CHANGE)) {
            return null;
        }
        // Skip creating snapshot if this transition is controlled by a remote animator which
        // doesn't need it.
        final ArraySet<Integer> activityTypes = new ArraySet<>();
        activityTypes.add(getActivityType());
        final RemoteAnimationAdapter adapter =
                mDisplayContent.mAppTransitionController.getRemoteAnimationOverride(
                        this, TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE, activityTypes);
        if (adapter != null && !adapter.getChangeNeedsSnapshot()) {
            return null;
        }
        return getSurfaceControl();
    }
    }


    @Override
    @Override
Loading