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