/*
 * 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 android.view.SurfaceControl.METADATA_OWNER_UID;
import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;

import static com.android.server.wm.AppWindowThumbnailProto.HEIGHT;
import static com.android.server.wm.AppWindowThumbnailProto.SURFACE_ANIMATOR;
import static com.android.server.wm.AppWindowThumbnailProto.WIDTH;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
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.MAX_ANIMATION_DURATION;

import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Binder;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Builder;
import android.view.SurfaceControl.Transaction;
import android.view.animation.Animation;

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

/**
 * Represents a surface that is displayed over an {@link AppWindowToken}
 */
class AppWindowThumbnail implements Animatable {

    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowThumbnail" : TAG_WM;

    private final AppWindowToken mAppToken;
    private final SurfaceControl mSurfaceControl;
    private final SurfaceAnimator mSurfaceAnimator;
    private final int mWidth;
    private final int mHeight;
    private final boolean mRelative;

    AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader) {
        this(t, appToken, thumbnailHeader, false /* relative */);
    }

    /**
     * @param t Transaction to create the thumbnail in.
     * @param appToken {@link AppWindowToken} to associate this thumbnail with.
     * @param thumbnailHeader A thumbnail or placeholder for thumbnail to initialize with.
     * @param relative Whether this thumbnail will be a child of appToken (and thus positioned
     *                 relative to it) or not.
     */
    AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader,
            boolean relative) {
        mAppToken = appToken;
        mRelative = relative;
        mSurfaceAnimator =
                new SurfaceAnimator(this, this::onAnimationFinished, appToken.mWmService);
        mWidth = thumbnailHeader.getWidth();
        mHeight = thumbnailHeader.getHeight();

        // Create a new surface for the thumbnail
        WindowState window = appToken.findMainWindow();

        // TODO: This should be attached as a child to the app token, once the thumbnail animations
        // use relative coordinates. Once we start animating task we can also consider attaching
        // this to the task.
        mSurfaceControl = appToken.makeSurface()
                .setName("thumbnail anim: " + appToken.toString())
                .setBufferSize(mWidth, mHeight)
                .setFormat(PixelFormat.TRANSLUCENT)
                .setMetadata(METADATA_WINDOW_TYPE, appToken.windowType)
                .setMetadata(METADATA_OWNER_UID,
                        window != null ? window.mOwnerUid : Binder.getCallingUid())
                .build();

        if (SHOW_TRANSACTIONS) {
            Slog.i(TAG, "  THUMBNAIL " + mSurfaceControl + ": CREATE");
        }

        // Transfer the thumbnail to the surface
        Surface drawSurface = new Surface();
        drawSurface.copyFrom(mSurfaceControl);
        drawSurface.attachAndQueueBuffer(thumbnailHeader);
        drawSurface.release();
        t.show(mSurfaceControl);

        // We parent the thumbnail to the task, and just place it on top of anything else in the
        // task.
        t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
        if (relative) {
            t.reparent(mSurfaceControl, appToken.getSurfaceControl());
        }
    }

    void startAnimation(Transaction t, Animation anim) {
        startAnimation(t, anim, null /* position */);
    }

    void startAnimation(Transaction t, Animation anim, Point position) {
        anim.restrictDuration(MAX_ANIMATION_DURATION);
        anim.scaleCurrentDuration(mAppToken.mWmService.getTransitionAnimationScaleLocked());
        mSurfaceAnimator.startAnimation(t, new LocalAnimationAdapter(
                new WindowAnimationSpec(anim, position,
                        mAppToken.getDisplayContent().mAppTransition.canSkipFirstFrame(),
                        mAppToken.mWmService.mWindowCornerRadius),
                mAppToken.mWmService.mSurfaceAnimationRunner), false /* hidden */);
    }

    /**
     * Start animation with existing adapter.
     */
    void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
        mSurfaceAnimator.startAnimation(t, anim, hidden);
    }

    private void onAnimationFinished() {
    }

    void setShowing(Transaction pendingTransaction, boolean show) {
        // TODO: Not needed anymore once thumbnail is attached to the app.
        if (show) {
            pendingTransaction.show(mSurfaceControl);
        } else {
            pendingTransaction.hide(mSurfaceControl);
        }
    }

    void destroy() {
        mSurfaceAnimator.cancelAnimation();
        getPendingTransaction().remove(mSurfaceControl);
    }

    /**
     * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
     * com.android.server.wm.AppWindowThumbnailProto}.
     *
     * @param proto Stream to write the AppWindowThumbnail object to.
     * @param fieldId Field Id of the AppWindowThumbnail as defined in the parent message.
     * @hide
     */
    void writeToProto(ProtoOutputStream proto, long fieldId) {
        final long token = proto.start(fieldId);
        proto.write(WIDTH, mWidth);
        proto.write(HEIGHT, mHeight);
        if (mSurfaceAnimator.isAnimating()) {
            mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
        }
        proto.end(token);
    }

    @Override
    public Transaction getPendingTransaction() {
        return mAppToken.getPendingTransaction();
    }

    @Override
    public void commitPendingTransaction() {
        mAppToken.commitPendingTransaction();
    }

    @Override
    public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
        t.setLayer(leash, Integer.MAX_VALUE);
        if (mRelative) {
            t.reparent(leash, mAppToken.getSurfaceControl());
        }
    }

    @Override
    public void onAnimationLeashDestroyed(Transaction t) {

        // TODO: Once attached to app token, we don't need to hide it immediately if thumbnail
        // became visible.
        t.hide(mSurfaceControl);
    }

    @Override
    public Builder makeAnimationLeash() {
        return mAppToken.makeSurface();
    }

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

    @Override
    public SurfaceControl getAnimationLeashParent() {
        return mAppToken.getAppAnimationLayer();
    }

    @Override
    public SurfaceControl getParentSurfaceControl() {
        return mAppToken.getParentSurfaceControl();
    }

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

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