11666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale/*
21666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * Copyright (C) 2016 The Android Open Source Project
31666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale *
41666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * Licensed under the Apache License, Version 2.0 (the "License");
51666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * you may not use this file except in compliance with the License.
61666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * You may obtain a copy of the License at
71666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale *
81666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale *      http://www.apache.org/licenses/LICENSE-2.0
91666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale *
101666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * Unless required by applicable law or agreed to in writing, software
111666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * distributed under the License is distributed on an "AS IS" BASIS,
121666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * See the License for the specific language governing permissions and
141666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * limitations under the License
151666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale */
161666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
171666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwalepackage com.android.server.wm;
181666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
19bdc646f5d514259d9aae975bac64363947db0d32Winson Chungimport static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
201893a6118ce09f60dc6ff91b5977da467bddb00eAndrii Kulianimport static android.app.ActivityManager.StackId.PINNED_STACK_ID;
21bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
22bdc646f5d514259d9aae975bac64363947db0d32Winson Chungimport android.app.ActivityManager.StackId;
231666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.app.RemoteAction;
241666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.content.res.Configuration;
251666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.graphics.Rect;
261666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.os.Handler;
271666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.os.Looper;
281666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.os.Message;
291666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.util.Slog;
301666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport android.util.SparseArray;
31bdc646f5d514259d9aae975bac64363947db0d32Winson Chungimport android.view.DisplayInfo;
32bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
331666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport com.android.server.UiThread;
341666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport com.android.internal.annotations.VisibleForTesting;
351666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
361666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport java.lang.ref.WeakReference;
371666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport java.util.List;
381666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
391666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
401666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport static com.android.server.wm.WindowContainer.POSITION_TOP;
411666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
421666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwaleimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
431666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
441666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale/**
451666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * Controller for the stack container. This is created by activity manager to link activity stacks
461666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * to the stack container they use in window manager.
471666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale *
481666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale * Test class: {@link StackWindowControllerTests}
491666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale */
501666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwalepublic class StackWindowController
511666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        extends WindowContainerController<TaskStack, StackWindowListener> {
521666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
531666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    final int mStackId;
541666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
551666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    private final H mHandler;
561666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
57bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    // Temp bounds only used in adjustConfigurationForBounds()
58bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    private final Rect mTmpRect = new Rect();
59bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    private final Rect mTmpStableInsets = new Rect();
60bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    private final Rect mTmpNonDecorInsets = new Rect();
61bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    private final Rect mTmpDisplayBounds = new Rect();
62bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
631666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public StackWindowController(int stackId, StackWindowListener listener,
641666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            int displayId, boolean onTop, Rect outBounds) {
651666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        this(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
661666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
671666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
681666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    @VisibleForTesting
691666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public StackWindowController(int stackId, StackWindowListener listener,
701666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            int displayId, boolean onTop, Rect outBounds, WindowManagerService service) {
711666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        super(listener, service);
721666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        mStackId = stackId;
731666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
741666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
751666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
761666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            final DisplayContent dc = mRoot.getDisplayContent(displayId);
771666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (dc == null) {
781666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                throw new IllegalArgumentException("Trying to add stackId=" + stackId
791666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                        + " to unknown displayId=" + displayId);
801666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
811666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
821666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            final TaskStack stack = dc.addStackToDisplay(stackId, onTop);
831666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            stack.setController(this);
841666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            getRawBounds(outBounds);
851666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
861666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
871666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
881666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    @Override
891666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public void removeContainer() {
901666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
911666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer != null) {
921666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                mContainer.removeIfPossible();
931666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                super.removeContainer();
941666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
951666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
961666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
971666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
98cd501ecd91bd7016639e8e62d4a739a01971f95cWale Ogunwale    public boolean isVisible() {
99cd501ecd91bd7016639e8e62d4a739a01971f95cWale Ogunwale        synchronized (mWindowMap) {
100cd501ecd91bd7016639e8e62d4a739a01971f95cWale Ogunwale            return mContainer != null && mContainer.isVisible();
101cd501ecd91bd7016639e8e62d4a739a01971f95cWale Ogunwale        }
102cd501ecd91bd7016639e8e62d4a739a01971f95cWale Ogunwale    }
103cd501ecd91bd7016639e8e62d4a739a01971f95cWale Ogunwale
10451c1b670224fa1598644426b472d51346dd22f30Andrii Kulian    public void reparent(int displayId, Rect outStackBounds, boolean onTop) {
1051666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
1061666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer == null) {
1071666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                throw new IllegalArgumentException("Trying to move unknown stackId=" + mStackId
1081666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                        + " to displayId=" + displayId);
1091666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1101666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1111666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            final DisplayContent targetDc = mRoot.getDisplayContent(displayId);
1121666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (targetDc == null) {
1131666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                throw new IllegalArgumentException("Trying to move stackId=" + mStackId
1141666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                        + " to unknown displayId=" + displayId);
1151666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1161666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
11751c1b670224fa1598644426b472d51346dd22f30Andrii Kulian            targetDc.moveStackToDisplay(mContainer, onTop);
1181666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            getRawBounds(outStackBounds);
1191666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
1201666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
1211666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1221666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public void positionChildAt(TaskWindowContainerController child, int position, Rect bounds,
1231666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            Configuration overrideConfig) {
1241666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
1251666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (DEBUG_STACK) Slog.i(TAG_WM, "positionChildAt: positioning task=" + child
1261666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                    + " at " + position);
1271666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (child.mContainer == null) {
1281666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                if (DEBUG_STACK) Slog.i(TAG_WM,
1291666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                        "positionChildAt: could not find task=" + this);
1301666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                return;
1311666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1321666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer == null) {
1331666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                if (DEBUG_STACK) Slog.i(TAG_WM,
1341666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                        "positionChildAt: could not find stack for task=" + mContainer);
1351666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                return;
1361666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1371666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            child.mContainer.positionAt(position, bounds, overrideConfig);
1381666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
1391666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
1401666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
1411666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1421666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public void positionChildAtTop(TaskWindowContainerController child, boolean includingParents) {
1431666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        if (child == null) {
1441666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            // TODO: Fix the call-points that cause this to happen.
1451666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            return;
1461666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
1471666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1481666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized(mWindowMap) {
1491666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            final Task childTask = child.mContainer;
1501666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (childTask == null) {
1511666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                Slog.e(TAG_WM, "positionChildAtTop: task=" + child + " not found");
1521666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                return;
1531666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1541666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.positionChildAt(POSITION_TOP, childTask, includingParents);
1551666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1561666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mService.mAppTransition.isTransitionSet()) {
1571666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                childTask.setSendingToBottom(false);
1581666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1591666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
1601666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
1611666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
1621666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1631666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public void positionChildAtBottom(TaskWindowContainerController child) {
1641666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        if (child == null) {
1651666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            // TODO: Fix the call-points that cause this to happen.
1661666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            return;
1671666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
1681666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1691666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized(mWindowMap) {
1701666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            final Task childTask = child.mContainer;
1711666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (childTask == null) {
1721666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                Slog.e(TAG_WM, "positionChildAtBottom: task=" + child + " not found");
1731666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                return;
1741666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1751666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.positionChildAt(POSITION_BOTTOM, childTask, false /* includingParents */);
1761666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1771666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mService.mAppTransition.isTransitionSet()) {
1781666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                childTask.setSendingToBottom(true);
1791666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1801666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
1811666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
1821666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
1831666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
1841666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    /**
1851666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale     * Re-sizes a stack and its containing tasks.
1861666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale     *
1871666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale     * @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
1881666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale     * @param configs Configurations for tasks in the resized stack, keyed by task id.
1891666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale     * @param taskBounds Bounds for tasks in the resized stack, keyed by task id.
1901666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale     * @return True if the stack is now fullscreen.
1911666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale     */
1921666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public boolean resize(Rect bounds, SparseArray<Configuration> configs,
1931666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            SparseArray<Rect> taskBounds, SparseArray<Rect> taskTempInsetBounds) {
1941666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
1951666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer == null) {
1961666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                throw new IllegalArgumentException("resizeStack: stack " + this + " not found.");
1971666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
1981666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            // We might trigger a configuration change. Save the current task bounds for freezing.
1991666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.prepareFreezingTaskBounds();
2001666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer.setBounds(bounds, configs, taskBounds, taskTempInsetBounds)
2011666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                    && mContainer.isVisible()) {
2021666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                mContainer.getDisplayContent().setLayoutNeeded();
2031666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                mService.mWindowPlacerLocked.performSurfacePlacement();
2041666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
2051666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            return mContainer.getRawFullscreen();
2061666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
2071666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
2081666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
209aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng    /**
210aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng     * @see TaskStack.getStackDockedModeBoundsLocked(Rect, Rect, Rect, boolean)
211aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng     */
212aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng   public void getStackDockedModeBounds(Rect currentTempTaskBounds, Rect outStackBounds,
213aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng           Rect outTempTaskBounds, boolean ignoreVisibility) {
2141666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
2151666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer != null) {
216aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng                mContainer.getStackDockedModeBoundsLocked(currentTempTaskBounds, outStackBounds,
217aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng                        outTempTaskBounds, ignoreVisibility);
2181666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                return;
2191666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
220aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng            outStackBounds.setEmpty();
221aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng            outTempTaskBounds.setEmpty();
2221666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
2231666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
2241666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
2251666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public void prepareFreezingTaskBounds() {
2261666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
2271666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer == null) {
2281666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                throw new IllegalArgumentException("prepareFreezingTaskBounds: stack " + this
2291666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                        + " not found.");
2301666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
2311666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.prepareFreezingTaskBounds();
2321666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
2331666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
2341666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
2351666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    private void getRawBounds(Rect outBounds) {
2361666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        if (mContainer.getRawFullscreen()) {
2371666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            outBounds.setEmpty();
2381666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        } else {
2391666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mContainer.getRawBounds(outBounds);
2401666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
2411666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
2421666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
2431666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public void getBounds(Rect outBounds) {
2441666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized (mWindowMap) {
2451666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (mContainer != null) {
2461666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                mContainer.getBounds(outBounds);
2471666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                return;
2481666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
2491666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            outBounds.setEmpty();
2501666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
2511666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
2521666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
253aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng    public void getBoundsForNewConfiguration(Rect outBounds) {
2541666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        synchronized(mWindowMap) {
255aa2b620cb76cb8a710c3c4500bc5f6975ddc7a84Matthew Ng            mContainer.getBoundsForNewConfiguration(outBounds);
2561666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
2571666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
2581666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
259bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    /**
260bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     * Adjusts the screen size in dp's for the {@param config} for the given params.
261bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     */
262bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds,
263bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth,
264bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            boolean overrideHeight, float density, Configuration config,
265bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            Configuration parentConfig) {
266bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        synchronized (mWindowMap) {
267bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            final TaskStack stack = mContainer;
268bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            final DisplayContent displayContent = stack.getDisplayContent();
269bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            final DisplayInfo di = displayContent.getDisplayInfo();
270bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
271bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            // Get the insets and display bounds
272bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
273bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    mTmpStableInsets);
274bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            mService.mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
275bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    mTmpNonDecorInsets);
276bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            mTmpDisplayBounds.set(0, 0, di.logicalWidth, di.logicalHeight);
277bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
278bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            int width;
279bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            int height;
2807566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee
2817566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee            final Rect parentAppBounds = parentConfig.appBounds;
2827566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee
2837566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee            config.setAppBounds(!bounds.isEmpty() ? bounds : null);
2847566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee            boolean intersectParentBounds = false;
2857566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee
286bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            if (StackId.tasksAreFloating(mStackId)) {
287bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                // Floating tasks should not be resized to the screen's bounds.
288bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
2891893a6118ce09f60dc6ff91b5977da467bddb00eAndrii Kulian                if (mStackId == PINNED_STACK_ID && bounds.width() == mTmpDisplayBounds.width() &&
290bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                        bounds.height() == mTmpDisplayBounds.height()) {
291bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    // If the bounds we are animating is the same as the fullscreen stack
292bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    // dimensions, then apply the same inset calculations that we normally do for
293bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    // the fullscreen stack, without intersecting it with the display bounds
294bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    stableBounds.inset(mTmpStableInsets);
295bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    nonDecorBounds.inset(mTmpNonDecorInsets);
2961893a6118ce09f60dc6ff91b5977da467bddb00eAndrii Kulian                    // Move app bounds to zero to apply intersection with parent correctly. They are
2971893a6118ce09f60dc6ff91b5977da467bddb00eAndrii Kulian                    // used only for evaluating width and height, so it's OK to move them around.
2981893a6118ce09f60dc6ff91b5977da467bddb00eAndrii Kulian                    config.appBounds.offsetTo(0, 0);
2997566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee                    intersectParentBounds = true;
300bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                }
301bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                width = (int) (stableBounds.width() / density);
302bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                height = (int) (stableBounds.height() / density);
303bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            } else {
304bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen
305bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                // area, i.e. the screen area without the system bars.
306bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                // Additionally task dimensions should not be bigger than its parents dimensions.
307bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                // The non decor inset are areas that could never be removed in Honeycomb. See
308bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
309bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                intersectDisplayBoundsExcludeInsets(nonDecorBounds,
310bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                        insetBounds != null ? insetBounds : bounds, mTmpNonDecorInsets,
311bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                        mTmpDisplayBounds, overrideWidth, overrideHeight);
312bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                intersectDisplayBoundsExcludeInsets(stableBounds,
313bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                        insetBounds != null ? insetBounds : bounds, mTmpStableInsets,
314bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                        mTmpDisplayBounds, overrideWidth, overrideHeight);
315bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                width = Math.min((int) (stableBounds.width() / density),
316bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                        parentConfig.screenWidthDp);
317bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                height = Math.min((int) (stableBounds.height() / density),
318bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                        parentConfig.screenHeightDp);
3197566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee                intersectParentBounds = true;
3207566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee            }
3217566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee
3227566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee            if (intersectParentBounds && config.appBounds != null) {
3237566d76c618a48b8dcc981dac3cab1e42f864063Bryce Lee                config.appBounds.intersect(parentAppBounds);
324bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            }
325bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
326bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            config.screenWidthDp = width;
327bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            config.screenHeightDp = height;
328bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            config.smallestScreenWidthDp = getSmallestWidthForTaskBounds(
329bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    insetBounds != null ? insetBounds : bounds, density);
330bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        }
331bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    }
332bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
333bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    /**
334bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     * Intersects the specified {@code inOutBounds} with the display frame that excludes the stable
335bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     * inset areas.
336bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     *
337bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     * @param inOutBounds The inOutBounds to subtract the stable inset areas from.
338bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     */
339bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    private void intersectDisplayBoundsExcludeInsets(Rect inOutBounds, Rect inInsetBounds,
340bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            Rect stableInsets, Rect displayBounds, boolean overrideWidth, boolean overrideHeight) {
341bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        mTmpRect.set(inInsetBounds);
342bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        mService.intersectDisplayInsetBounds(displayBounds, stableInsets, mTmpRect);
343bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        int leftInset = mTmpRect.left - inInsetBounds.left;
344bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        int topInset = mTmpRect.top - inInsetBounds.top;
345bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect.right;
346bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect.bottom;
347bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        inOutBounds.inset(leftInset, topInset, rightInset, bottomInset);
348bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    }
349bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
350bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    /**
351bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     * Calculates the smallest width for a task given the {@param bounds}.
352bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     *
353bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     * @return the smallest width to be used in the Configuration, in dips
354bdc646f5d514259d9aae975bac64363947db0d32Winson Chung     */
355bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    private int getSmallestWidthForTaskBounds(Rect bounds, float density) {
356bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        final DisplayContent displayContent = mContainer.getDisplayContent();
357bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
358bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
359bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        if (bounds == null || (bounds.width() == displayInfo.logicalWidth &&
360bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                bounds.height() == displayInfo.logicalHeight)) {
361bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            // If the bounds are fullscreen, return the value of the fullscreen configuration
362bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            return displayContent.getConfiguration().smallestScreenWidthDp;
363bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        } else if (StackId.tasksAreFloating(mStackId)) {
364bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            // For floating tasks, calculate the smallest width from the bounds of the task
365bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            return (int) (Math.min(bounds.width(), bounds.height()) / density);
366bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        } else {
367bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            // Iterating across all screen orientations, and return the minimum of the task
368bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            // width taking into account that the bounds might change because the snap algorithm
369bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            // snaps to a different value
370bdc646f5d514259d9aae975bac64363947db0d32Winson Chung            return displayContent.getDockedDividerController()
371bdc646f5d514259d9aae975bac64363947db0d32Winson Chung                    .getSmallestWidthDpForBounds(bounds);
372bdc646f5d514259d9aae975bac64363947db0d32Winson Chung        }
373bdc646f5d514259d9aae975bac64363947db0d32Winson Chung    }
374bdc646f5d514259d9aae975bac64363947db0d32Winson Chung
3751666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    void requestResize(Rect bounds) {
3761666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        mHandler.obtainMessage(H.REQUEST_RESIZE, bounds).sendToTarget();
3771666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
3781666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
3791666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    @Override
3801666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    public String toString() {
3811666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        return "{StackWindowController stackId=" + mStackId + "}";
3821666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
3831666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
3841666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    private static final class H extends Handler {
3851666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
3861666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        static final int REQUEST_RESIZE = 0;
3871666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
3881666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        private final WeakReference<StackWindowController> mController;
3891666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
3901666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        H(WeakReference<StackWindowController> controller, Looper looper) {
3911666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            super(looper);
3921666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            mController = controller;
3931666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
3941666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale
3951666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        @Override
3961666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        public void handleMessage(Message msg) {
3971666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            final StackWindowController controller = mController.get();
3981666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            final StackWindowListener listener = (controller != null)
3991666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                    ? controller.mListener : null;
4001666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            if (listener == null) {
4011666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                return;
4021666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
4031666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            switch (msg.what) {
4041666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                case REQUEST_RESIZE:
4051666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                    listener.requestResize((Rect) msg.obj);
4061666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale                    break;
4071666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale            }
4081666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale        }
4091666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale    }
4101666e317dc1a17e9435246ec6c8209dbb6ee3696Wale Ogunwale}
411