/*
 * Copyright (C) 2016 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 android.app.WindowConfiguration;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.DisplayInfo;

import com.android.internal.annotations.VisibleForTesting;

import java.lang.ref.WeakReference;

import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

/**
 * Controller for the stack container. This is created by activity manager to link activity stacks
 * to the stack container they use in window manager.
 *
 * Test class: {@link StackWindowControllerTests}
 */
public class StackWindowController
        extends WindowContainerController<TaskStack, StackWindowListener> {

    private final int mStackId;

    private final H mHandler;

    // Temp bounds only used in adjustConfigurationForBounds()
    private final Rect mTmpRect = new Rect();
    private final Rect mTmpStableInsets = new Rect();
    private final Rect mTmpNonDecorInsets = new Rect();
    private final Rect mTmpDisplayBounds = new Rect();

    public StackWindowController(int stackId, StackWindowListener listener, int displayId,
            boolean onTop, Rect outBounds) {
        this(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
    }

    @VisibleForTesting
    public StackWindowController(int stackId, StackWindowListener listener,
            int displayId, boolean onTop, Rect outBounds, WindowManagerService service) {
        super(listener, service);
        mStackId = stackId;
        mHandler = new H(new WeakReference<>(this), service.mH.getLooper());

        synchronized (mWindowMap) {
            final DisplayContent dc = mRoot.getDisplayContent(displayId);
            if (dc == null) {
                throw new IllegalArgumentException("Trying to add stackId=" + stackId
                        + " to unknown displayId=" + displayId);
            }

            dc.createStack(stackId, onTop, this);
            getRawBounds(outBounds);
        }
    }

    @Override
    public void removeContainer() {
        synchronized (mWindowMap) {
            if (mContainer != null) {
                mContainer.removeIfPossible();
                super.removeContainer();
            }
        }
    }

    public void reparent(int displayId, Rect outStackBounds, boolean onTop) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                throw new IllegalArgumentException("Trying to move unknown stackId=" + mStackId
                        + " to displayId=" + displayId);
            }

            final DisplayContent targetDc = mRoot.getDisplayContent(displayId);
            if (targetDc == null) {
                throw new IllegalArgumentException("Trying to move stackId=" + mStackId
                        + " to unknown displayId=" + displayId);
            }

            targetDc.moveStackToDisplay(mContainer, onTop);
            getRawBounds(outStackBounds);
        }
    }

    public void positionChildAt(TaskWindowContainerController child, int position) {
        synchronized (mWindowMap) {
            if (DEBUG_STACK) Slog.i(TAG_WM, "positionChildAt: positioning task=" + child
                    + " at " + position);
            if (child.mContainer == null) {
                if (DEBUG_STACK) Slog.i(TAG_WM,
                        "positionChildAt: could not find task=" + this);
                return;
            }
            if (mContainer == null) {
                if (DEBUG_STACK) Slog.i(TAG_WM,
                        "positionChildAt: could not find stack for task=" + mContainer);
                return;
            }
            child.mContainer.positionAt(position);
            mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
        }
    }

    public void positionChildAtTop(TaskWindowContainerController child, boolean includingParents) {
        if (child == null) {
            // TODO: Fix the call-points that cause this to happen.
            return;
        }

        synchronized(mWindowMap) {
            final Task childTask = child.mContainer;
            if (childTask == null) {
                Slog.e(TAG_WM, "positionChildAtTop: task=" + child + " not found");
                return;
            }
            mContainer.positionChildAt(POSITION_TOP, childTask, includingParents);

            if (mService.mAppTransition.isTransitionSet()) {
                childTask.setSendingToBottom(false);
            }
            mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
        }
    }

    public void positionChildAtBottom(TaskWindowContainerController child,
            boolean includingParents) {
        if (child == null) {
            // TODO: Fix the call-points that cause this to happen.
            return;
        }

        synchronized(mWindowMap) {
            final Task childTask = child.mContainer;
            if (childTask == null) {
                Slog.e(TAG_WM, "positionChildAtBottom: task=" + child + " not found");
                return;
            }
            mContainer.positionChildAt(POSITION_BOTTOM, childTask, includingParents);

            if (mService.mAppTransition.isTransitionSet()) {
                childTask.setSendingToBottom(true);
            }
            mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
        }
    }

    /**
     * Re-sizes a stack and its containing tasks.
     *
     * @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
     * @param taskBounds Bounds for tasks in the resized stack, keyed by task id.
     * @param taskTempInsetBounds Inset bounds for individual tasks, keyed by task id.
     */
    public void resize(Rect bounds, SparseArray<Rect> taskBounds,
            SparseArray<Rect> taskTempInsetBounds) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                throw new IllegalArgumentException("resizeStack: stack " + this + " not found.");
            }
            // We might trigger a configuration change. Save the current task bounds for freezing.
            mContainer.prepareFreezingTaskBounds();
            if (mContainer.setBounds(bounds, taskBounds, taskTempInsetBounds)
                    && mContainer.isVisible()) {
                mContainer.getDisplayContent().setLayoutNeeded();
                mService.mWindowPlacerLocked.performSurfacePlacement();
            }
        }
    }

    public void onPipAnimationEndResize() {
        synchronized (mService.mWindowMap) {
            mContainer.onPipAnimationEndResize();
        }
    }

    /**
     * @see TaskStack.getStackDockedModeBoundsLocked(Rect, Rect, Rect, boolean)
     */
   public void getStackDockedModeBounds(Rect currentTempTaskBounds, Rect outStackBounds,
           Rect outTempTaskBounds, boolean ignoreVisibility) {
        synchronized (mWindowMap) {
            if (mContainer != null) {
                mContainer.getStackDockedModeBoundsLocked(currentTempTaskBounds, outStackBounds,
                        outTempTaskBounds, ignoreVisibility);
                return;
            }
            outStackBounds.setEmpty();
            outTempTaskBounds.setEmpty();
        }
    }

    public void prepareFreezingTaskBounds() {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                throw new IllegalArgumentException("prepareFreezingTaskBounds: stack " + this
                        + " not found.");
            }
            mContainer.prepareFreezingTaskBounds();
        }
    }

    public void getRawBounds(Rect outBounds) {
        synchronized (mWindowMap) {
            if (mContainer.matchParentBounds()) {
                outBounds.setEmpty();
            } else {
                mContainer.getRawBounds(outBounds);
            }
        }
    }

    public void getBounds(Rect outBounds) {
        synchronized (mWindowMap) {
            if (mContainer != null) {
                mContainer.getBounds(outBounds);
                return;
            }
            outBounds.setEmpty();
        }
    }

    public void getBoundsForNewConfiguration(Rect outBounds) {
        synchronized(mWindowMap) {
            mContainer.getBoundsForNewConfiguration(outBounds);
        }
    }

    /**
     * Adjusts the screen size in dp's for the {@param config} for the given params. The provided
     * params represent the desired state of a configuration change. Since this utility is used
     * before mContainer has been updated, any relevant properties (like {@param windowingMode})
     * need to be passed in.
     */
    public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds,
            Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth,
            boolean overrideHeight, float density, Configuration config,
            Configuration parentConfig, int windowingMode) {
        synchronized (mWindowMap) {
            final TaskStack stack = mContainer;
            final DisplayContent displayContent = stack.getDisplayContent();
            final DisplayInfo di = displayContent.getDisplayInfo();
            final DisplayCutout displayCutout = di.displayCutout;

            // Get the insets and display bounds
            mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
                    displayCutout, mTmpStableInsets);
            mService.mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
                    displayCutout, mTmpNonDecorInsets);
            mTmpDisplayBounds.set(0, 0, di.logicalWidth, di.logicalHeight);

            int width;
            int height;

            final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();

            config.windowConfiguration.setBounds(bounds);
            config.windowConfiguration.setAppBounds(!bounds.isEmpty() ? bounds : null);
            boolean intersectParentBounds = false;

            if (WindowConfiguration.isFloating(windowingMode)) {
                // Floating tasks should not be resized to the screen's bounds.

                if (windowingMode == WindowConfiguration.WINDOWING_MODE_PINNED
                        && bounds.width() == mTmpDisplayBounds.width()
                        && bounds.height() == mTmpDisplayBounds.height()) {
                    // If the bounds we are animating is the same as the fullscreen stack
                    // dimensions, then apply the same inset calculations that we normally do for
                    // the fullscreen stack, without intersecting it with the display bounds
                    stableBounds.inset(mTmpStableInsets);
                    nonDecorBounds.inset(mTmpNonDecorInsets);
                    // Move app bounds to zero to apply intersection with parent correctly. They are
                    // used only for evaluating width and height, so it's OK to move them around.
                    config.windowConfiguration.getAppBounds().offsetTo(0, 0);
                    intersectParentBounds = true;
                }
                width = (int) (stableBounds.width() / density);
                height = (int) (stableBounds.height() / density);
            } else {
                // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen
                // area, i.e. the screen area without the system bars.
                // Additionally task dimensions should not be bigger than its parents dimensions.
                // The non decor inset are areas that could never be removed in Honeycomb. See
                // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
                intersectDisplayBoundsExcludeInsets(nonDecorBounds,
                        insetBounds != null ? insetBounds : bounds, mTmpNonDecorInsets,
                        mTmpDisplayBounds, overrideWidth, overrideHeight);
                intersectDisplayBoundsExcludeInsets(stableBounds,
                        insetBounds != null ? insetBounds : bounds, mTmpStableInsets,
                        mTmpDisplayBounds, overrideWidth, overrideHeight);
                width = Math.min((int) (stableBounds.width() / density),
                        parentConfig.screenWidthDp);
                height = Math.min((int) (stableBounds.height() / density),
                        parentConfig.screenHeightDp);
                intersectParentBounds = true;
            }

            if (intersectParentBounds && config.windowConfiguration.getAppBounds() != null) {
                config.windowConfiguration.getAppBounds().intersect(parentAppBounds);
            }

            config.screenWidthDp = width;
            config.screenHeightDp = height;
            config.smallestScreenWidthDp = getSmallestWidthForTaskBounds(
                    insetBounds != null ? insetBounds : bounds, density, windowingMode);
        }
    }

    /**
     * Intersects the specified {@code inOutBounds} with the display frame that excludes the stable
     * inset areas.
     *
     * @param inOutBounds The inOutBounds to subtract the stable inset areas from.
     */
    private void intersectDisplayBoundsExcludeInsets(Rect inOutBounds, Rect inInsetBounds,
            Rect stableInsets, Rect displayBounds, boolean overrideWidth, boolean overrideHeight) {
        mTmpRect.set(inInsetBounds);
        mService.intersectDisplayInsetBounds(displayBounds, stableInsets, mTmpRect);
        int leftInset = mTmpRect.left - inInsetBounds.left;
        int topInset = mTmpRect.top - inInsetBounds.top;
        int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect.right;
        int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect.bottom;
        inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
    }

    /**
     * Calculates the smallest width for a task given the target {@param bounds} and
     * {@param windowingMode}. Avoid using values from mContainer since they can be out-of-date.
     *
     * @return the smallest width to be used in the Configuration, in dips
     */
    private int getSmallestWidthForTaskBounds(Rect bounds, float density, int windowingMode) {
        final DisplayContent displayContent = mContainer.getDisplayContent();
        final DisplayInfo displayInfo = displayContent.getDisplayInfo();

        if (bounds == null || (bounds.width() == displayInfo.logicalWidth &&
                bounds.height() == displayInfo.logicalHeight)) {
            // If the bounds are fullscreen, return the value of the fullscreen configuration
            return displayContent.getConfiguration().smallestScreenWidthDp;
        } else if (WindowConfiguration.isFloating(windowingMode)) {
            // For floating tasks, calculate the smallest width from the bounds of the task
            return (int) (Math.min(bounds.width(), bounds.height()) / density);
        } else {
            // Iterating across all screen orientations, and return the minimum of the task
            // width taking into account that the bounds might change because the snap algorithm
            // snaps to a different value
            return displayContent.getDockedDividerController()
                    .getSmallestWidthDpForBounds(bounds);
        }
    }

    void requestResize(Rect bounds) {
        mHandler.obtainMessage(H.REQUEST_RESIZE, bounds).sendToTarget();
    }

    @Override
    public String toString() {
        return "{StackWindowController stackId=" + mStackId + "}";
    }

    private static final class H extends Handler {

        static final int REQUEST_RESIZE = 0;

        private final WeakReference<StackWindowController> mController;

        H(WeakReference<StackWindowController> controller, Looper looper) {
            super(looper);
            mController = controller;
        }

        @Override
        public void handleMessage(Message msg) {
            final StackWindowController controller = mController.get();
            final StackWindowListener listener = (controller != null)
                    ? controller.mListener : null;
            if (listener == null) {
                return;
            }
            switch (msg.what) {
                case REQUEST_RESIZE:
                    listener.requestResize((Rect) msg.obj);
                    break;
            }
        }
    }
}
