/*
 * Copyright (C) 2017 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.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;

import android.platform.test.annotations.Presubmit;
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Builder;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;

import androidx.test.filters.SmallTest;

import com.android.server.wm.SurfaceAnimator.Animatable;
import com.android.server.wm.SurfaceAnimator.AnimationType;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.io.PrintWriter;

/**
 * Test class for {@link SurfaceAnimatorTest}.
 *
 * Build/Install/Run:
 *  atest WmTests:SurfaceAnimatorTest
 */
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class SurfaceAnimatorTest extends WindowTestsBase {

    @Mock AnimationAdapter mSpec;
    @Mock AnimationAdapter mSpec2;
    @Mock Transaction mTransaction;

    private SurfaceSession mSession = new SurfaceSession();
    private MyAnimatable mAnimatable;
    private MyAnimatable mAnimatable2;
    private DeferFinishAnimatable mDeferFinishAnimatable;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        mAnimatable = new MyAnimatable(mWm, mSession, mTransaction);
        mAnimatable2 = new MyAnimatable(mWm, mSession, mTransaction);
        mDeferFinishAnimatable = new DeferFinishAnimatable(mWm, mSession, mTransaction);
    }

    @After
    public void tearDown() {
        mAnimatable = null;
        mAnimatable2 = null;
        mDeferFinishAnimatable = null;
        mSession.kill();
        mSession = null;
    }

    @Test
    public void testRunAnimation() {
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_RECENTS);
        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                OnAnimationFinishedCallback.class);
        assertAnimating(mAnimatable);
        verify(mTransaction).reparent(eq(mAnimatable.mSurface), eq(mAnimatable.mLeash));
        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_RECENTS),
                callbackCaptor.capture());

        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_RECENTS, mSpec);
        assertNotAnimating(mAnimatable);
        assertTrue(mAnimatable.mFinishedCallbackCalled);
        assertEquals(ANIMATION_TYPE_RECENTS, mAnimatable.mFinishedAnimationType);
        verify(mTransaction).remove(eq(mAnimatable.mLeash));
        // TODO: Verify reparenting once we use mPendingTransaction to reparent it back
    }

    @Test
    public void testOverrideAnimation() {
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);
        final SurfaceControl firstLeash = mAnimatable.mLeash;
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);

        verify(mTransaction).remove(eq(firstLeash));
        assertFalse(mAnimatable.mFinishedCallbackCalled);

        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                OnAnimationFinishedCallback.class);
        assertAnimating(mAnimatable);
        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
                callbackCaptor.capture());

        // First animation was finished, but this shouldn't cancel the second animation
        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
        assertTrue(mAnimatable.mSurfaceAnimator.isAnimating());

        // Second animation was finished
        verify(mSpec2).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
                callbackCaptor.capture());
        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec2);
        assertNotAnimating(mAnimatable);
        assertTrue(mAnimatable.mFinishedCallbackCalled);
        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
    }

    @Test
    public void testCancelAnimation() {
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);
        assertAnimating(mAnimatable);
        mAnimatable.mSurfaceAnimator.cancelAnimation();
        assertNotAnimating(mAnimatable);
        verify(mSpec).onAnimationCancelled(any());
        assertTrue(mAnimatable.mFinishedCallbackCalled);
        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
        verify(mTransaction).remove(eq(mAnimatable.mLeash));
    }

    @Test
    public void testCancelWithNullFinishCallbackAnimation() {
        SurfaceAnimator animator = new SurfaceAnimator(mAnimatable, null, mWm);
        animator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);
        assertTrue(animator.isAnimating());
        assertNotNull(animator.getAnimation());
        animator.cancelAnimation();
        assertFalse(animator.isAnimating());
        assertNull(animator.getAnimation());
        verify(mSpec).onAnimationCancelled(any());
        verify(mTransaction).remove(eq(mAnimatable.mLeash));
    }

    @Test
    public void testDelayingAnimationStart() {
        mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);
        verifyZeroInteractions(mSpec);
        assertAnimating(mAnimatable);
        assertTrue(mAnimatable.mSurfaceAnimator.isAnimationStartDelayed());
        mAnimatable.mSurfaceAnimator.endDelayingAnimationStart();
        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION), any());
    }

    @Test
    public void testDelayingAnimationStartAndCancelled() {
        mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);
        mAnimatable.mSurfaceAnimator.cancelAnimation();
        verifyZeroInteractions(mSpec);
        assertNotAnimating(mAnimatable);
        assertTrue(mAnimatable.mFinishedCallbackCalled);
        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
        verify(mTransaction).remove(eq(mAnimatable.mLeash));
    }

    @Test
    public void testTransferAnimation() {
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);

        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                OnAnimationFinishedCallback.class);
        verify(mSpec).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
                callbackCaptor.capture());
        final SurfaceControl leash = mAnimatable.mLeash;

        mAnimatable2.mSurfaceAnimator.transferAnimation(mAnimatable.mSurfaceAnimator);
        assertNotAnimating(mAnimatable);
        assertAnimating(mAnimatable2);
        assertEquals(leash, mAnimatable2.mSurfaceAnimator.mLeash);
        verify(mTransaction, never()).remove(eq(leash));
        callbackCaptor.getValue().onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
        assertNotAnimating(mAnimatable2);
        assertTrue(mAnimatable2.mFinishedCallbackCalled);
        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mAnimatable.mFinishedAnimationType);
        verify(mTransaction).remove(eq(leash));
    }

    @Test
    public void testOnAnimationLeashLostWhenAnimatableParentSurfaceControlNull() {
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);
        spyOn(mAnimatable);

        // Verify onAnimationLeashLost will be called even animatable's parent surface control lost.
        doReturn(null).when(mAnimatable).getParentSurfaceControl();
        mAnimatable.mSurfaceAnimator.cancelAnimation();

        final SurfaceControl leash = mAnimatable.mLeash;
        verify(mTransaction).remove(eq(leash));
        verify(mAnimatable).onAnimationLeashLost(mTransaction);
    }

    @Test
    public void testDeferFinish() {

        // Start animation
        final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);

        // Finish the animation but then make sure we are deferring.
        onFinishedCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
        assertAnimating(mDeferFinishAnimatable);

        // Now end defer finishing.
        mDeferFinishAnimatable.mEndDeferFinishCallback.run();
        assertNotAnimating(mAnimatable2);
        assertTrue(mDeferFinishAnimatable.mFinishedCallbackCalled);
        assertEquals(ANIMATION_TYPE_APP_TRANSITION, mDeferFinishAnimatable.mFinishedAnimationType);
        verify(mTransaction).remove(eq(mDeferFinishAnimatable.mLeash));
    }

    @Test
    public void testDeferFinishDoNotFinishNextAnimation() {
        // Start the first animation.
        final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
        onFinishedCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, mSpec);
        // The callback is the resetAndInvokeFinish in {@link SurfaceAnimator#getFinishedCallback}.
        final Runnable firstDeferFinishCallback = mDeferFinishAnimatable.mEndDeferFinishCallback;

        // Start the second animation.
        mDeferFinishAnimatable.mSurfaceAnimator.cancelAnimation();
        startDeferFinishAnimatable(mSpec2);
        mDeferFinishAnimatable.mFinishedCallbackCalled = false;

        // Simulate the first deferred callback is executed from
        // {@link AnimatingActivityRegistry#endDeferringFinished}.
        firstDeferFinishCallback.run();
        // The second animation should not be finished.
        assertFalse(mDeferFinishAnimatable.mFinishedCallbackCalled);
    }

    @Test
    public void testDeferFinishFromAdapter() {

        DeferredFinishAdapter deferredFinishAdapter = new DeferredFinishAdapter();
        // Start animation
        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, deferredFinishAdapter,
                true /* hidden */,
                ANIMATION_TYPE_APP_TRANSITION);
        assertAnimating(mAnimatable);
        deferredFinishAdapter.mFinishCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION,
                deferredFinishAdapter);

        assertAnimating(mAnimatable);
        assertFalse(mAnimatable.mFinishedCallbackCalled);
        // Now end defer finishing.
        deferredFinishAdapter.mEndDeferFinishCallback.run();
        assertNotAnimating(mAnimatable);
        assertTrue(mAnimatable.mFinishedCallbackCalled);
        verify(mTransaction).remove(eq(deferredFinishAdapter.mAnimationLeash));
    }

    private OnAnimationFinishedCallback startDeferFinishAnimatable(AnimationAdapter anim) {
        mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, anim,
                true /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                OnAnimationFinishedCallback.class);
        assertAnimating(mDeferFinishAnimatable);
        verify(anim).startAnimation(any(), any(), eq(ANIMATION_TYPE_APP_TRANSITION),
                callbackCaptor.capture());
        return callbackCaptor.getValue();
    }

    private void assertAnimating(MyAnimatable animatable) {
        assertTrue(animatable.mSurfaceAnimator.isAnimating());
        assertNotNull(animatable.mSurfaceAnimator.getAnimation());
    }

    private void assertNotAnimating(MyAnimatable animatable) {
        assertFalse(animatable.mSurfaceAnimator.isAnimating());
        assertNull(animatable.mSurfaceAnimator.getAnimation());
    }

    private static class MyAnimatable implements Animatable {

        private final SurfaceSession mSession;
        private final Transaction mTransaction;
        final SurfaceControl mParent;
        final SurfaceControl mSurface;
        final SurfaceAnimator mSurfaceAnimator;
        SurfaceControl mLeash;
        boolean mFinishedCallbackCalled;
        @AnimationType int mFinishedAnimationType;

        MyAnimatable(WindowManagerService wm, SurfaceSession session, Transaction transaction) {
            mSession = session;
            mTransaction = transaction;
            mParent = wm.makeSurfaceBuilder(mSession)
                    .setName("test surface parent")
                    .build();
            mSurface = wm.makeSurfaceBuilder(mSession)
                    .setName("test surface")
                    .build();
            mFinishedCallbackCalled = false;
            mLeash = null;
            mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, wm);
        }

        @Override
        public Transaction getPendingTransaction() {
            return mTransaction;
        }

        @Override
        public void commitPendingTransaction() {
        }

        @Override
        public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
        }

        @Override
        public void onAnimationLeashLost(Transaction t) {
        }

        @Override
        public Builder makeAnimationLeash() {
            return new SurfaceControl.Builder(mSession) {

                @Override
                public SurfaceControl build() {
                    mLeash = super.build();
                    return mLeash;
                }
            }.setParent(mParent);
        }

        @Override
        public SurfaceControl getAnimationLeashParent() {
            return mParent;
        }

        @Override
        public SurfaceControl getSurfaceControl() {
            return mSurface;
        }

        @Override
        public SurfaceControl getParentSurfaceControl() {
            return mParent;
        }

        @Override
        public int getSurfaceWidth() {
            return 1;
        }

        @Override
        public int getSurfaceHeight() {
            return 1;
        }

        private final SurfaceAnimator.OnAnimationFinishedCallback mFinishedCallback = (
                type, anim) -> {
            mFinishedCallbackCalled = true;
            mFinishedAnimationType = type;
        };
    }

    private static class DeferFinishAnimatable extends MyAnimatable {

        Runnable mEndDeferFinishCallback;

        DeferFinishAnimatable(WindowManagerService wm, SurfaceSession session,
                Transaction transaction) {
            super(wm, session, transaction);
        }

        @Override
        public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
            mEndDeferFinishCallback = endDeferFinishCallback;
            return true;
        }
    }

    private static class DeferredFinishAdapter implements AnimationAdapter {

        private Runnable mEndDeferFinishCallback;
        private OnAnimationFinishedCallback mFinishCallback;
        private SurfaceControl mAnimationLeash;

        @Override
        public boolean getShowWallpaper() {
            return true;
        }

        @Override
        public void startAnimation(SurfaceControl animationLeash, Transaction t, int type,
                OnAnimationFinishedCallback finishCallback) {
            mFinishCallback = finishCallback;
            mAnimationLeash = animationLeash;
        }

        @Override
        public void onAnimationCancelled(SurfaceControl animationLeash) {
        }

        @Override
        public long getDurationHint() {
            return 100;
        }

        @Override
        public long getStatusBarTransitionsStartTime() {
            return 100;
        }

        @Override
        public void dump(PrintWriter pw, String prefix) {
        }

        @Override
        public void dumpDebug(ProtoOutputStream proto) {
        }

        @Override
        public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
            mEndDeferFinishCallback = endDeferFinishCallback;
            return true;
        }
    }
}
