/*
 * Copyright (C) 2010 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.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING;
import static com.android.server.wm.ScreenRotationAnimationProto.STARTED;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;

import com.android.server.protolog.common.ProtoLog;

import java.io.PrintWriter;

/**
 * This class handles the rotation animation when the device is rotated.
 *
 * <p>
 * The screen rotation animation is composed of 4 different part:
 * <ul>
 * <li> The screenshot: <p>
 *     A screenshot of the whole screen prior the change of orientation is taken to hide the
 *     element resizing below. The screenshot is then animated to rotate and cross-fade to
 *     the new orientation with the content in the new orientation.
 *
 * <li> The windows on the display: <p>y
 *      Once the device is rotated, the screen and its content are in the new orientation. The
 *      animation first rotate the new content into the old orientation to then be able to
 *      animate to the new orientation
 *
 * <li> The exiting Blackframe: <p>
 *     Because the change of orientation might change the width and height of the content (i.e
 *     when rotating from portrait to landscape) we "crop" the new content using black frames
 *     around the screenshot so the new content does not go beyond the screenshot's bounds
 *
 * <li> The entering Blackframe: <p>
 *     The enter Blackframe is similar to the exit Blackframe but is only used when a custom
 *     rotation animation is used and matches the new content size instead of the screenshot.
 * </ul>
 *
 * Each part has its own Surface which are then animated by {@link SurfaceAnimator}s.
 */
class ScreenRotationAnimation {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM;

    /*
     * Layers for screen rotation animation. We put these layers above
     * WINDOW_FREEZE_LAYER so that screen freeze will cover all windows.
     */
    private static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER;
    private static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE;
    private static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1;
    private static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2;

    private final Context mContext;
    private final DisplayContent mDisplayContent;
    private final float[] mTmpFloats = new float[9];
    private final Transformation mRotateExitTransformation = new Transformation();
    private final Transformation mRotateEnterTransformation = new Transformation();
    // Complete transformations being applied.
    private final Transformation mExitTransformation = new Transformation();
    private final Transformation mEnterTransformation = new Transformation();
    private final Matrix mFrameInitialMatrix = new Matrix();
    private final Matrix mSnapshotInitialMatrix = new Matrix();
    private final Matrix mSnapshotFinalMatrix = new Matrix();
    private final Matrix mExitFrameFinalMatrix = new Matrix();
    private final WindowManagerService mService;
    private SurfaceControl mEnterBlackFrameLayer;
    private SurfaceControl mRotationLayer;
    private SurfaceControl mSurfaceControl;
    private BlackFrame mEnteringBlackFrame;
    private int mWidth, mHeight;

    private int mOriginalRotation;
    private int mOriginalWidth, mOriginalHeight;
    private int mCurRotation;

    private Rect mOriginalDisplayRect = new Rect();
    private Rect mCurrentDisplayRect = new Rect();
    // The current active animation to move from the old to the new rotated
    // state.  Which animation is run here will depend on the old and new
    // rotations.
    private Animation mRotateExitAnimation;
    private Animation mRotateEnterAnimation;
    private Animation mRotateAlphaAnimation;
    private boolean mStarted;
    private boolean mAnimRunning;
    private boolean mFinishAnimReady;
    private long mFinishAnimStartTime;
    private boolean mForceDefaultOrientation;
    private BlackFrame mExitingBlackFrame;
    private SurfaceRotationAnimationController mSurfaceRotationAnimationController;

    public ScreenRotationAnimation(Context context, DisplayContent displayContent,
            boolean fixedToUserRotation, boolean isSecure, WindowManagerService service) {
        mService = service;
        mContext = context;
        mDisplayContent = displayContent;
        displayContent.getBounds(mOriginalDisplayRect);

        // Screenshot does NOT include rotation!
        final Display display = displayContent.getDisplay();
        int originalRotation = display.getRotation();
        final int originalWidth;
        final int originalHeight;
        DisplayInfo displayInfo = displayContent.getDisplayInfo();
        if (fixedToUserRotation) {
            // Emulated orientation.
            mForceDefaultOrientation = true;
            originalWidth = displayContent.mBaseDisplayWidth;
            originalHeight = displayContent.mBaseDisplayHeight;
        } else {
            // Normal situation
            originalWidth = displayInfo.logicalWidth;
            originalHeight = displayInfo.logicalHeight;
        }
        if (originalRotation == Surface.ROTATION_90
                || originalRotation == Surface.ROTATION_270) {
            mWidth = originalHeight;
            mHeight = originalWidth;
        } else {
            mWidth = originalWidth;
            mHeight = originalHeight;
        }

        mOriginalRotation = originalRotation;
        mOriginalWidth = originalWidth;
        mOriginalHeight = originalHeight;
        mSurfaceRotationAnimationController = new SurfaceRotationAnimationController();

        final SurfaceControl.Transaction t = mService.mTransactionFactory.get();
        try {
            mRotationLayer = displayContent.makeOverlay()
                    .setName("RotationLayer")
                    .setContainerLayer()
                    .build();

            mEnterBlackFrameLayer = displayContent.makeOverlay()
                    .setName("EnterBlackFrameLayer")
                    .setContainerLayer()
                    .build();

            mSurfaceControl = displayContent.makeSurface(null)
                    .setName("ScreenshotSurface")
                    .setParent(mRotationLayer)
                    .setBufferSize(mWidth, mHeight)
                    .setSecure(isSecure)
                    .build();

            // In case display bounds change, screenshot buffer and surface may mismatch so set a
            // scaling mode.
            SurfaceControl.Transaction t2 = mService.mTransactionFactory.get();
            t2.setOverrideScalingMode(mSurfaceControl, Surface.SCALING_MODE_SCALE_TO_WINDOW);
            t2.apply(true /* sync */);

            // Capture a screenshot into the surface we just created.
            final int displayId = display.getDisplayId();
            final Surface surface = mService.mSurfaceFactory.get();
            surface.copyFrom(mSurfaceControl);
            SurfaceControl.ScreenshotGraphicBuffer gb =
                    mService.mDisplayManagerInternal.screenshot(displayId);
            if (gb != null) {
                try {
                    surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
                            gb.getColorSpace());
                } catch (RuntimeException e) {
                    Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
                }
                // If the screenshot contains secure layers, we have to make sure the
                // screenshot surface we display it in also has FLAG_SECURE so that
                // the user can not screenshot secure layers via the screenshot surface.
                if (gb.containsSecureLayers()) {
                    t.setSecure(mSurfaceControl, true);
                }
                t.setLayer(mRotationLayer, SCREEN_FREEZE_LAYER_BASE);
                t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
                t.setAlpha(mSurfaceControl, 0);
                t.show(mRotationLayer);
                t.show(mSurfaceControl);
            } else {
                Slog.w(TAG, "Unable to take screenshot of display " + displayId);
            }
            surface.destroy();
        } catch (OutOfResourcesException e) {
            Slog.w(TAG, "Unable to allocate freeze surface", e);
        }

        ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
                    "  FREEZE %s: CREATE", mSurfaceControl);
        setRotation(t, originalRotation);
        t.apply();
    }

    private static void createRotationMatrix(int rotation, int width, int height,
            Matrix outMatrix) {
        switch (rotation) {
            case Surface.ROTATION_0:
                outMatrix.reset();
                break;
            case Surface.ROTATION_90:
                outMatrix.setRotate(90, 0, 0);
                outMatrix.postTranslate(height, 0);
                break;
            case Surface.ROTATION_180:
                outMatrix.setRotate(180, 0, 0);
                outMatrix.postTranslate(width, height);
                break;
            case Surface.ROTATION_270:
                outMatrix.setRotate(270, 0, 0);
                outMatrix.postTranslate(0, width);
                break;
        }
    }

    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
        proto.write(STARTED, mStarted);
        proto.write(ANIMATION_RUNNING, mAnimRunning);
        proto.end(token);
    }

    boolean hasScreenshot() {
        return mSurfaceControl != null;
    }

    private void setRotationTransform(SurfaceControl.Transaction t, Matrix matrix) {
        if (mRotationLayer == null) {
            return;
        }
        matrix.getValues(mTmpFloats);
        float x = mTmpFloats[Matrix.MTRANS_X];
        float y = mTmpFloats[Matrix.MTRANS_Y];
        if (mForceDefaultOrientation) {
            mDisplayContent.getBounds(mCurrentDisplayRect);
            x -= mCurrentDisplayRect.left;
            y -= mCurrentDisplayRect.top;
        }
        t.setPosition(mRotationLayer, x, y);
        t.setMatrix(mRotationLayer,
                mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
                mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);

        t.setAlpha(mSurfaceControl, (float) 1.0);
        t.setAlpha(mRotationLayer, (float) 1.0);
        t.show(mRotationLayer);
    }

    public void printTo(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
        pw.print(" mWidth="); pw.print(mWidth);
        pw.print(" mHeight="); pw.println(mHeight);
        pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
        if (mExitingBlackFrame != null) {
            mExitingBlackFrame.printTo(prefix + "  ", pw);
        }
        pw.print(prefix);
        pw.print("mEnteringBlackFrame=");
        pw.println(mEnteringBlackFrame);
        if (mEnteringBlackFrame != null) {
            mEnteringBlackFrame.printTo(prefix + "  ", pw);
        }
        pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
        pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
        pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
        pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
        pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
        pw.print(" mAnimRunning="); pw.print(mAnimRunning);
        pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
        pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
        pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
        pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
        pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
        pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
        pw.print(prefix); pw.print("mExitTransformation=");
        mExitTransformation.printShortString(pw); pw.println();
        pw.print(prefix); pw.print("mEnterTransformation=");
        mEnterTransformation.printShortString(pw); pw.println();
        pw.print(prefix); pw.print("mFrameInitialMatrix=");
        mFrameInitialMatrix.printShortString(pw);
        pw.println();
        pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
        mSnapshotInitialMatrix.printShortString(pw);
        pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
        pw.println();
        pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
        mExitFrameFinalMatrix.printShortString(pw);
        pw.println();
        pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
        if (mForceDefaultOrientation) {
            pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
            pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
        }
    }

    public void setRotation(SurfaceControl.Transaction t, int rotation) {
        mCurRotation = rotation;

        // Compute the transformation matrix that must be applied
        // to the snapshot to make it stay in the same original position
        // with the current screen rotation.
        int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
        createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);

        setRotationTransform(t, mSnapshotInitialMatrix);
    }

    /**
     * Returns true if animating.
     */
    private boolean startAnimation(SurfaceControl.Transaction t, long maxAnimationDuration,
            float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
        if (mSurfaceControl == null) {
            // Can't do animation.
            return false;
        }
        if (mStarted) {
            return true;
        }

        mStarted = true;

        // Figure out how the screen has moved from the original rotation.
        int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);

        mRotateAlphaAnimation = AnimationUtils.loadAnimation(mContext,
                com.android.internal.R.anim.screen_rotate_alpha);

        final boolean customAnim;
        if (exitAnim != 0 && enterAnim != 0) {
            customAnim = true;
            mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
            mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
        } else {
            customAnim = false;
            switch (delta) {
                case Surface.ROTATION_0:
                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_0_exit);
                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_0_enter);
                    break;
                case Surface.ROTATION_90:
                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_plus_90_exit);
                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_plus_90_enter);
                    break;
                case Surface.ROTATION_180:
                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_180_exit);
                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_180_enter);
                    break;
                case Surface.ROTATION_270:
                    mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_minus_90_exit);
                    mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
                            com.android.internal.R.anim.screen_rotate_minus_90_enter);
                    break;
            }
        }

        // Initialize the animations.  This is a hack, redefining what "parent"
        // means to allow supplying the last and next size.  In this definition
        // "%p" is the original (let's call it "previous") size, and "%" is the
        // screen's current/new size.
        mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
        mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
        mAnimRunning = false;
        mFinishAnimReady = false;
        mFinishAnimStartTime = -1;

        mRotateExitAnimation.restrictDuration(maxAnimationDuration);
        mRotateExitAnimation.scaleCurrentDuration(animationScale);
        mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
        mRotateEnterAnimation.scaleCurrentDuration(animationScale);
        mRotateAlphaAnimation.restrictDuration(maxAnimationDuration);
        mRotateAlphaAnimation.scaleCurrentDuration(animationScale);

        if (!customAnim && mExitingBlackFrame == null) {
            try {
                // Compute the transformation matrix that must be applied
                // the the black frame to make it stay in the initial position
                // before the new screen rotation.  This is different than the
                // snapshot transformation because the snapshot is always based
                // of the native orientation of the screen, not the orientation
                // we were last in.
                createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);

                final Rect outer;
                final Rect inner;
                if (mForceDefaultOrientation) {
                    // Going from a smaller Display to a larger Display, add curtains to sides
                    // or top and bottom. Going from a larger to smaller display will result in
                    // no BlackSurfaces being constructed.
                    outer = mCurrentDisplayRect;
                    inner = mOriginalDisplayRect;
                } else {
                    outer = new Rect(-mWidth, -mHeight, mWidth * 2, mHeight * 2);
                    inner = new Rect(0, 0, mWidth, mHeight);
                }
                mExitingBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                        SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation,
                        mRotationLayer);
            } catch (OutOfResourcesException e) {
                Slog.w(TAG, "Unable to allocate black surface", e);
            }
        }

        if (customAnim && mEnteringBlackFrame == null) {
            try {
                Rect outer = new Rect(-finalWidth, -finalHeight,
                        finalWidth * 2, finalHeight * 2);
                Rect inner = new Rect(0, 0, finalWidth, finalHeight);
                mEnteringBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                        SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false, mEnterBlackFrameLayer);
            } catch (OutOfResourcesException e) {
                Slog.w(TAG, "Unable to allocate black surface", e);
            }
        }

        mSurfaceRotationAnimationController.startAnimation();
        return true;
    }

    /**
     * Returns true if animating.
     */
    public boolean dismiss(SurfaceControl.Transaction t, long maxAnimationDuration,
            float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
        if (mSurfaceControl == null) {
            // Can't do animation.
            return false;
        }
        if (!mStarted) {
            startAnimation(t, maxAnimationDuration, animationScale, finalWidth, finalHeight,
                    exitAnim, enterAnim);
        }
        if (!mStarted) {
            return false;
        }
        mFinishAnimReady = true;
        return true;
    }

    public void kill() {
        if (mSurfaceRotationAnimationController != null) {
            mSurfaceRotationAnimationController.cancel();
            mSurfaceRotationAnimationController = null;
        }
        if (mSurfaceControl != null) {
            ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "  FREEZE %s: DESTROY", mSurfaceControl);
            mSurfaceControl = null;
            SurfaceControl.Transaction t = mService.mTransactionFactory.get();
            if (mRotationLayer != null) {
                if (mRotationLayer.isValid()) {
                    t.remove(mRotationLayer);
                }
                mRotationLayer = null;
            }
            if (mEnterBlackFrameLayer != null) {
                if (mEnterBlackFrameLayer.isValid()) {
                    t.remove(mEnterBlackFrameLayer);
                }
                mEnterBlackFrameLayer = null;
            }
            t.apply();
        }
        if (mExitingBlackFrame != null) {
            mExitingBlackFrame.kill();
            mExitingBlackFrame = null;
        }
        if (mEnteringBlackFrame != null) {
            mEnteringBlackFrame.kill();
            mEnteringBlackFrame = null;
        }
        if (mRotateExitAnimation != null) {
            mRotateExitAnimation.cancel();
            mRotateExitAnimation = null;
        }
        if (mRotateEnterAnimation != null) {
            mRotateEnterAnimation.cancel();
            mRotateEnterAnimation = null;
        }
        if (mRotateAlphaAnimation != null) {
            mRotateAlphaAnimation.cancel();
            mRotateAlphaAnimation = null;
        }
    }

    public boolean isAnimating() {
        return mSurfaceRotationAnimationController != null
                && mSurfaceRotationAnimationController.isAnimating();
    }

    public boolean isRotating() {
        return mCurRotation != mOriginalRotation;
    }

    public Transformation getEnterTransformation() {
        return mEnterTransformation;
    }

    /**
     * Utility class that runs a {@link ScreenRotationAnimation} on the {@link
     * SurfaceAnimationRunner}.
     * <p>
     * The rotation animation is divided into the following hierarchy:
     * <ul>
     * <li> A first rotation layer, containing the blackframes. This layer is animated by the
     * "screen_rotate_X_exit" that applies a scale and rotate and where X is value of the rotation.
     *     <ul>
     *         <li> A child layer containing the screenshot on which is added an animation of it's
     *     alpha channel ("screen_rotate_alpha") and that will rotate with his parent layer.</li>
     *     </ul>
     * <li> A second rotation layer used when custom animations are passed in
     * {@link ScreenRotationAnimation#startAnimation(
     *     SurfaceControl.Transaction, long, float, int, int, int, int)}.
     * </ul>
     * <p>
     * Thus an {@link LocalAnimationAdapter.AnimationSpec} is created for each of
     * this three {@link SurfaceControl}s which then delegates the animation to the
     * {@link ScreenRotationAnimation}.
     */
    class SurfaceRotationAnimationController {
        private SurfaceAnimator mDisplayAnimator;
        private SurfaceAnimator mEnterBlackFrameAnimator;
        private SurfaceAnimator mScreenshotRotationAnimator;
        private SurfaceAnimator mRotateScreenAnimator;

        /**
         * Start the rotation animation of the display and the screenshot on the
         * {@link SurfaceAnimationRunner}.
         */
        void startAnimation() {
            mRotateScreenAnimator = startScreenshotAlphaAnimation();
            mDisplayAnimator = startDisplayRotation();
            if (mExitingBlackFrame != null) {
                mScreenshotRotationAnimator = startScreenshotRotationAnimation();
            }
            if (mEnteringBlackFrame != null) {
                mEnterBlackFrameAnimator = startEnterBlackFrameAnimation();
            }
        }

        private SimpleSurfaceAnimatable.Builder initializeBuilder() {
            return new SimpleSurfaceAnimatable.Builder()
                    .setPendingTransactionSupplier(mDisplayContent::getPendingTransaction)
                    .setCommitTransactionRunnable(mDisplayContent::commitPendingTransaction)
                    .setAnimationLeashSupplier(mDisplayContent::makeOverlay);
        }

        private SurfaceAnimator startDisplayRotation() {
            return startAnimation(initializeBuilder()
                            .setAnimationLeashParent(mDisplayContent.getSurfaceControl())
                            .setSurfaceControl(mDisplayContent.getWindowingLayer())
                            .setParentSurfaceControl(mDisplayContent.getSurfaceControl())
                            .setWidth(mDisplayContent.getSurfaceWidth())
                            .setHeight(mDisplayContent.getSurfaceHeight())
                            .build(),
                    createWindowAnimationSpec(mRotateEnterAnimation),
                    this::onAnimationEnd);
        }

        private SurfaceAnimator startScreenshotAlphaAnimation() {
            return startAnimation(initializeBuilder()
                            .setSurfaceControl(mSurfaceControl)
                            .setAnimationLeashParent(mRotationLayer)
                            .setWidth(mWidth)
                            .setHeight(mHeight)
                            .build(),
                    createWindowAnimationSpec(mRotateAlphaAnimation),
                    this::onAnimationEnd);
        }

        private SurfaceAnimator startEnterBlackFrameAnimation() {
            return startAnimation(initializeBuilder()
                            .setSurfaceControl(mEnterBlackFrameLayer)
                            .setAnimationLeashParent(mDisplayContent.getOverlayLayer())
                            .build(),
                    createWindowAnimationSpec(mRotateEnterAnimation),
                    this::onAnimationEnd);
        }

        private SurfaceAnimator startScreenshotRotationAnimation() {
            return startAnimation(initializeBuilder()
                            .setSurfaceControl(mRotationLayer)
                            .setAnimationLeashParent(mDisplayContent.getOverlayLayer())
                            .build(),
                    createWindowAnimationSpec(mRotateExitAnimation),
                    this::onAnimationEnd);
        }

        private WindowAnimationSpec createWindowAnimationSpec(Animation mAnimation) {
            return new WindowAnimationSpec(mAnimation, new Point(0, 0) /* position */,
                    false /* canSkipFirstFrame */, 0 /* WindowCornerRadius */);
        }

        /**
         * Start an animation defined by animationSpec on a new {@link SurfaceAnimator}.
         *
         * @param animatable The animatable used for the animation.
         * @param animationSpec                The spec of the animation.
         * @param animationFinishedCallback    Callback passed to the {@link SurfaceAnimator} and
         *                                    called when the animation finishes.
         * @return The newly created {@link SurfaceAnimator} that as been started.
         */
        private SurfaceAnimator startAnimation(
                SurfaceAnimator.Animatable animatable,
                LocalAnimationAdapter.AnimationSpec animationSpec,
                Runnable animationFinishedCallback) {
            SurfaceAnimator animator = new SurfaceAnimator(
                    animatable, animationFinishedCallback, mService);

            LocalAnimationAdapter localAnimationAdapter = new LocalAnimationAdapter(
                    animationSpec, mService.mSurfaceAnimationRunner);

            animator.startAnimation(mDisplayContent.getPendingTransaction(),
                    localAnimationAdapter, false);
            return animator;
        }

        private void onAnimationEnd() {
            synchronized (mService.mGlobalLock) {
                if (isAnimating()) {
                    ProtoLog.v(WM_DEBUG_ORIENTATION,
                            "ScreenRotation sill animating: mDisplayAnimator: %s\n"
                                    + "mEnterBlackFrameAnimator: "
                                    + "%s\nmRotateScreenAnimator: %s\n"
                                    + "mScreenshotRotationAnimator: %s",
                            mDisplayAnimator != null
                                    ? mDisplayAnimator.isAnimating() : null,
                            mEnterBlackFrameAnimator != null
                                    ? mEnterBlackFrameAnimator.isAnimating() : null,
                            mRotateScreenAnimator != null
                                    ? mRotateScreenAnimator.isAnimating() : null,
                            mScreenshotRotationAnimator != null
                                    ? mScreenshotRotationAnimator.isAnimating() : null
                    );
                    return;
                }
                ProtoLog.d(WM_DEBUG_ORIENTATION, "ScreenRotationAnimation onAnimationEnd");
                mEnterBlackFrameAnimator = null;
                mScreenshotRotationAnimator = null;
                mRotateScreenAnimator = null;
                mService.mAnimator.mBulkUpdateParams |= WindowSurfacePlacer.SET_UPDATE_ROTATION;
                kill();
                mService.updateRotation(false, false);
                AccessibilityController accessibilityController = mService.mAccessibilityController;

                if (accessibilityController != null) {
                    // We just finished rotation animation which means we did not
                    // announce the rotation and waited for it to end, announce now.
                    accessibilityController.onRotationChangedLocked(mDisplayContent);
                }
            }
        }

        public void cancel() {
            if (mEnterBlackFrameAnimator != null) {
                mEnterBlackFrameAnimator.cancelAnimation();
            }

            if (mScreenshotRotationAnimator != null) {
                mScreenshotRotationAnimator.cancelAnimation();
            }

            if (mRotateScreenAnimator != null) {
                mRotateScreenAnimator.cancelAnimation();
            }

            if (mDisplayAnimator != null) {
                mDisplayAnimator.cancelAnimation();
            }
        }

        public boolean isAnimating() {
            return mDisplayAnimator != null && mDisplayAnimator.isAnimating()
                    || mEnterBlackFrameAnimator != null && mEnterBlackFrameAnimator.isAnimating()
                    || mRotateScreenAnimator != null && mRotateScreenAnimator.isAnimating()
                    || mScreenshotRotationAnimator != null
                    && mScreenshotRotationAnimator.isAnimating();
        }
    }
}
