/*
 * Copyright (C) 2019 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.AnimationAdapterProto.REMOTE;
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_REMOTE_ANIMATIONS;

import android.graphics.Point;
import android.os.SystemClock;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.function.Consumer;

/**
 * An animation adapter for wallpaper windows.
 */
class WallpaperAnimationAdapter implements AnimationAdapter {
    private static final String TAG = "WallpaperAnimationAdapter";

    private final WallpaperWindowToken mWallpaperToken;
    private SurfaceControl mCapturedLeash;
    private SurfaceAnimator.OnAnimationFinishedCallback mCapturedLeashFinishCallback;

    private long mDurationHint;
    private long mStatusBarTransitionDelay;

    private Consumer<WallpaperAnimationAdapter> mAnimationCanceledRunnable;
    private RemoteAnimationTarget mTarget;

    WallpaperAnimationAdapter(WallpaperWindowToken wallpaperToken,
            long durationHint, long statusBarTransitionDelay,
            Consumer<WallpaperAnimationAdapter> animationCanceledRunnable) {
        mWallpaperToken = wallpaperToken;
        mDurationHint = durationHint;
        mStatusBarTransitionDelay = statusBarTransitionDelay;
        mAnimationCanceledRunnable = animationCanceledRunnable;
    }

    /**
     * Creates and starts remote animations for all the visible wallpaper windows.
     *
     * @return RemoteAnimationTarget[] targets for all the visible wallpaper windows
     */
    public static RemoteAnimationTarget[] startWallpaperAnimations(WindowManagerService service,
            long durationHint, long statusBarTransitionDelay,
            Consumer<WallpaperAnimationAdapter> animationCanceledRunnable,
            ArrayList<WallpaperAnimationAdapter> adaptersOut) {
        final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
        service.mRoot.forAllWallpaperWindows(wallpaperWindow -> {
            if (!wallpaperWindow.getDisplayContent().mWallpaperController.isWallpaperVisible()) {
                if (DEBUG_REMOTE_ANIMATIONS || DEBUG_RECENTS_ANIMATIONS) {
                    Slog.d(TAG, "\tNot visible=" + wallpaperWindow);
                }
                return;
            }

            if (DEBUG_REMOTE_ANIMATIONS || DEBUG_RECENTS_ANIMATIONS) {
                Slog.d(TAG, "\tvisible=" + wallpaperWindow);
            }
            final WallpaperAnimationAdapter wallpaperAdapter = new WallpaperAnimationAdapter(
                    wallpaperWindow, durationHint, statusBarTransitionDelay,
                    animationCanceledRunnable);
            wallpaperWindow.startAnimation(wallpaperWindow.getPendingTransaction(),
                    wallpaperAdapter, false /* hidden */);
            targets.add(wallpaperAdapter.createRemoteAnimationTarget());
            adaptersOut.add(wallpaperAdapter);
        });
        return targets.toArray(new RemoteAnimationTarget[targets.size()]);
    }

    /**
     * Create a remote animation target for this animation adapter.
     */
    RemoteAnimationTarget createRemoteAnimationTarget() {
        mTarget = new RemoteAnimationTarget(-1, -1, getLeash(), false, null, null,
                mWallpaperToken.getPrefixOrderIndex(), new Point(), null,
                mWallpaperToken.getWindowConfiguration(), true, null, null);
        return mTarget;
    }

    /**
     * @return the leash for this animation (only valid after the wallpaper window surface animation
     * has started).
     */
    SurfaceControl getLeash() {
        return mCapturedLeash;
    }

    /**
     * @return the callback to call to clean up when the animation has finished.
     */
    SurfaceAnimator.OnAnimationFinishedCallback getLeashFinishedCallback() {
        return mCapturedLeashFinishCallback;
    }

    /**
     * @return the wallpaper window
     */
    WallpaperWindowToken getToken() {
        return mWallpaperToken;
    }

    @Override
    public boolean getShowWallpaper() {
        // Not used
        return false;
    }

    @Override
    public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t,
            SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
        if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "startAnimation");

        // Restore z-layering until client has a chance to modify it.
        t.setLayer(animationLeash, mWallpaperToken.getPrefixOrderIndex());
        mCapturedLeash = animationLeash;
        mCapturedLeashFinishCallback = finishCallback;
    }

    @Override
    public void onAnimationCancelled(SurfaceControl animationLeash) {
        if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "onAnimationCancelled");
        mAnimationCanceledRunnable.accept(this);
    }

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

    @Override
    public long getStatusBarTransitionsStartTime() {
        return SystemClock.uptimeMillis() + mStatusBarTransitionDelay;
    }

    @Override
    public void dump(PrintWriter pw, String prefix) {
        pw.print(prefix);
        pw.print("token=");
        pw.println(mWallpaperToken);
        if (mTarget != null) {
            pw.print(prefix);
            pw.println("Target:");
            mTarget.dump(pw, prefix + "  ");
        } else {
            pw.print(prefix);
            pw.println("Target: null");
        }
    }

    @Override
    public void writeToProto(ProtoOutputStream proto) {
        final long token = proto.start(REMOTE);
        if (mTarget != null) {
            mTarget.writeToProto(proto, TARGET);
        }
        proto.end(token);
    }
}
