1c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner/* 2c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * Copyright (C) 2013 The Android Open Source Project 3c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * 4c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * Licensed under the Apache License, Version 2.0 (the "License"); 5c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * you may not use this file except in compliance with the License. 6c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * You may obtain a copy of the License at 7c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * 8c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * http://www.apache.org/licenses/LICENSE-2.0 9c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * 10c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * Unless required by applicable law or agreed to in writing, software 11c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * distributed under the License is distributed on an "AS IS" BASIS, 12c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * See the License for the specific language governing permissions and 14c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * limitations under the License. 15c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner */ 16c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 17c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautnerpackage com.android.server.wm; 18c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 19c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautnerimport android.graphics.Rect; 20a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.util.Slog; 21c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 229e4f28cfa157fff89e42859edc9cce546508491fCraig Mautnerimport static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 23a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport static com.android.server.wm.WindowManagerService.DEBUG_STACK; 24a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport static com.android.server.wm.WindowManagerService.TAG; 259e4f28cfa157fff89e42859edc9cce546508491fCraig Mautner 2600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautnerimport java.io.PrintWriter; 27d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner 28c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautnerpublic class StackBox { 295a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */ 3005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner public static final int TASK_STACK_GOES_BEFORE = 0; 315a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */ 32c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner public static final int TASK_STACK_GOES_AFTER = 1; 335a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner /** Used with {@link WindowManagerService#createStack}. Horizontal to left of. */ 345a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner public static final int TASK_STACK_TO_LEFT_OF = 2; 355a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner /** Used with {@link WindowManagerService#createStack}. Horizontal to right of. */ 365a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner public static final int TASK_STACK_TO_RIGHT_OF = 3; 37967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** Used with {@link WindowManagerService#createStack}. Vertical: lower t/b Rect values. */ 385a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner public static final int TASK_STACK_GOES_ABOVE = 4; 39967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** Used with {@link WindowManagerService#createStack}. Vertical: higher t/b Rect values. */ 405a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner public static final int TASK_STACK_GOES_BELOW = 5; 41967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** Used with {@link WindowManagerService#createStack}. Put on a higher layer on display. */ 425a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner public static final int TASK_STACK_GOES_OVER = 6; 43967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */ 445a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner public static final int TASK_STACK_GOES_UNDER = 7; 45c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 465ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner static int sCurrentBoxId = 0; 475ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner 485ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner /** Unique id for this box */ 495ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner final int mStackBoxId; 505ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner 5105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner /** The service */ 5205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner final WindowManagerService mService; 5305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner 5400af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** The display this box sits in. */ 55c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner final DisplayContent mDisplayContent; 5600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 5700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this 5800af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * is this entire size of mDisplayContent. */ 594cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner StackBox mParent; 6000af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 6100af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** First child, this is null exactly when mStack is non-null. */ 62c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner StackBox mFirst; 6300af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 6400af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Second child, this is null exactly when mStack is non-null. */ 65c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner StackBox mSecond; 6600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 6700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Stack of Tasks, this is null exactly when mFirst and mSecond are non-null. */ 68c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner TaskStack mStack; 6900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 7000af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Content limits relative to the DisplayContent this sits in. */ 71967212cb542e6eeb308678367b53381bff984c31Craig Mautner Rect mBounds = new Rect(); 7200af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 7300af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Relative orientation of mFirst and mSecond. */ 7400af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner boolean mVertical; 7500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 76967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** Fraction of mBounds to devote to mFirst, remainder goes to mSecond */ 77967212cb542e6eeb308678367b53381bff984c31Craig Mautner float mWeight; 78967212cb542e6eeb308678367b53381bff984c31Craig Mautner 7900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Dirty flag. Something inside this or some descendant of this has changed. */ 80c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner boolean layoutNeeded; 8100af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 82d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner /** True if this StackBox sits below the Status Bar. */ 83d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner boolean mUnderStatusBar; 84d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner 85967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */ 86967212cb542e6eeb308678367b53381bff984c31Craig Mautner Rect mTmpRect = new Rect(); 87967212cb542e6eeb308678367b53381bff984c31Craig Mautner 8805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner StackBox(WindowManagerService service, DisplayContent displayContent, StackBox parent) { 895ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner synchronized (StackBox.class) { 905ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner mStackBoxId = sCurrentBoxId++; 915ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner } 925ff12101722874f5e7b0cadf06f4c53f4ec4b917Craig Mautner 9305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mService = service; 94c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner mDisplayContent = displayContent; 95967212cb542e6eeb308678367b53381bff984c31Craig Mautner mParent = parent; 96c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 97c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 98c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner /** Propagate #layoutNeeded bottom up. */ 99c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner void makeDirty() { 100c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner layoutNeeded = true; 101c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner if (mParent != null) { 102c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner mParent.makeDirty(); 103c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 104c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 105c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 10600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** 1075a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner * Determine if a particular StackBox is this one or a descendant of this one. 1085a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner * @param stackBoxId The StackBox being searched for. 1095a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner * @return true if the specified StackBox matches this or one of its descendants. 11000af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner */ 1115a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner boolean contains(int stackBoxId) { 112dc725fe93b05c38b47a967fdbbc003be915a2b76Craig Mautner return mStackBoxId == stackBoxId || 113dc725fe93b05c38b47a967fdbbc003be915a2b76Craig Mautner (mStack == null && (mFirst.contains(stackBoxId) || mSecond.contains(stackBoxId))); 11400af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner } 11500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 116cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner /** 117cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner * Return the stackId of the stack that intersects the passed point. 118cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner * @param x coordinate of point. 119cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner * @param y coordinate of point. 120cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner * @return -1 if point is outside of mBounds, otherwise the stackId of the containing stack. 121cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner */ 122cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner int stackIdFromPoint(int x, int y) { 123cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner if (!mBounds.contains(x, y)) { 124cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner return -1; 125cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner } 126cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner if (mStack != null) { 127cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner return mStack.mStackId; 128cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner } 129cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner int stackId = mFirst.stackIdFromPoint(x, y); 130cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner if (stackId >= 0) { 131cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner return stackId; 132cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner } 133cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner return mSecond.stackIdFromPoint(x, y); 134cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner } 135cf910b0c714b2ca90ea0013e5695850506a1d36fCraig Mautner 1364cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner /** Determine if this StackBox is the first child or second child. 1374cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner * @return true if this is the first child. 138967212cb542e6eeb308678367b53381bff984c31Craig Mautner */ 1394cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner boolean isFirstChild() { 14005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return mParent != null && mParent.mFirst == this; 141967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 142967212cb542e6eeb308678367b53381bff984c31Craig Mautner 143967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** Returns the bounds of the specified TaskStack if it is contained in this StackBox. 144967212cb542e6eeb308678367b53381bff984c31Craig Mautner * @param stackId the TaskStack to find the bounds of. 145967212cb542e6eeb308678367b53381bff984c31Craig Mautner * @return a new Rect with the bounds of stackId if it is within this StackBox, null otherwise. 146967212cb542e6eeb308678367b53381bff984c31Craig Mautner */ 147967212cb542e6eeb308678367b53381bff984c31Craig Mautner Rect getStackBounds(int stackId) { 148967212cb542e6eeb308678367b53381bff984c31Craig Mautner if (mStack != null) { 149967212cb542e6eeb308678367b53381bff984c31Craig Mautner return mStack.mStackId == stackId ? new Rect(mBounds) : null; 150967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 151967212cb542e6eeb308678367b53381bff984c31Craig Mautner Rect bounds = mFirst.getStackBounds(stackId); 152967212cb542e6eeb308678367b53381bff984c31Craig Mautner if (bounds != null) { 153967212cb542e6eeb308678367b53381bff984c31Craig Mautner return bounds; 154967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 155967212cb542e6eeb308678367b53381bff984c31Craig Mautner return mSecond.getStackBounds(stackId); 156967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 157967212cb542e6eeb308678367b53381bff984c31Craig Mautner 15800af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** 15900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * Create a new TaskStack relative to a specified one by splitting the StackBox containing 16000af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * the specified TaskStack into two children. The size and position each of the new StackBoxes 16100af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * is determined by the passed parameters. 16200af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * @param stackId The id of the new TaskStack to create. 1635a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner * @param relativeStackBoxId The id of the StackBox to place the new TaskStack next to. 16400af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * @param position One of the static TASK_STACK_GOES_xxx positions defined in this class. 16500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * @param weight The percentage size of the parent StackBox to devote to the new TaskStack. 16600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * @return The new TaskStack. 16700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner */ 1685a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) { 1695a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner if (mStackBoxId != relativeStackBoxId) { 1705a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner // This is not the targeted StackBox. 1715a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner if (mStack != null) { 1725a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner return null; 1735a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner } 1745a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner // Propagate the split to see if the targeted StackBox is in either sub box. 1755a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight); 176967212cb542e6eeb308678367b53381bff984c31Craig Mautner if (stack != null) { 177c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner return stack; 178c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 1795a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner return mSecond.split(stackId, relativeStackBoxId, position, weight); 180c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 181c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 182967212cb542e6eeb308678367b53381bff984c31Craig Mautner // Found it! 18305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner TaskStack stack = new TaskStack(mService, stackId, mDisplayContent); 184967212cb542e6eeb308678367b53381bff984c31Craig Mautner TaskStack firstStack; 185967212cb542e6eeb308678367b53381bff984c31Craig Mautner TaskStack secondStack; 1865a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner if (position == TASK_STACK_GOES_BEFORE) { 1875a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner // TODO: Test Configuration here for LTR/RTL. 1885a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner position = TASK_STACK_TO_LEFT_OF; 1895a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner } else if (position == TASK_STACK_GOES_AFTER) { 1905a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner // TODO: Test Configuration here for LTR/RTL. 1915a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner position = TASK_STACK_TO_RIGHT_OF; 1925a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner } 193967212cb542e6eeb308678367b53381bff984c31Craig Mautner switch (position) { 194967212cb542e6eeb308678367b53381bff984c31Craig Mautner default: 1955a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner case TASK_STACK_TO_LEFT_OF: 1965a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner case TASK_STACK_TO_RIGHT_OF: 197967212cb542e6eeb308678367b53381bff984c31Craig Mautner mVertical = false; 1985a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner if (position == TASK_STACK_TO_LEFT_OF) { 199967212cb542e6eeb308678367b53381bff984c31Craig Mautner mWeight = weight; 200967212cb542e6eeb308678367b53381bff984c31Craig Mautner firstStack = stack; 201967212cb542e6eeb308678367b53381bff984c31Craig Mautner secondStack = mStack; 202967212cb542e6eeb308678367b53381bff984c31Craig Mautner } else { 203967212cb542e6eeb308678367b53381bff984c31Craig Mautner mWeight = 1.0f - weight; 204967212cb542e6eeb308678367b53381bff984c31Craig Mautner firstStack = mStack; 205967212cb542e6eeb308678367b53381bff984c31Craig Mautner secondStack = stack; 206967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 207967212cb542e6eeb308678367b53381bff984c31Craig Mautner break; 208967212cb542e6eeb308678367b53381bff984c31Craig Mautner case TASK_STACK_GOES_ABOVE: 209967212cb542e6eeb308678367b53381bff984c31Craig Mautner case TASK_STACK_GOES_BELOW: 210967212cb542e6eeb308678367b53381bff984c31Craig Mautner mVertical = true; 211967212cb542e6eeb308678367b53381bff984c31Craig Mautner if (position == TASK_STACK_GOES_ABOVE) { 212967212cb542e6eeb308678367b53381bff984c31Craig Mautner mWeight = weight; 213967212cb542e6eeb308678367b53381bff984c31Craig Mautner firstStack = stack; 214967212cb542e6eeb308678367b53381bff984c31Craig Mautner secondStack = mStack; 215967212cb542e6eeb308678367b53381bff984c31Craig Mautner } else { 216967212cb542e6eeb308678367b53381bff984c31Craig Mautner mWeight = 1.0f - weight; 217967212cb542e6eeb308678367b53381bff984c31Craig Mautner firstStack = mStack; 218967212cb542e6eeb308678367b53381bff984c31Craig Mautner secondStack = stack; 219967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 220967212cb542e6eeb308678367b53381bff984c31Craig Mautner break; 221c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 222967212cb542e6eeb308678367b53381bff984c31Craig Mautner 22305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mFirst = new StackBox(mService, mDisplayContent, this); 224967212cb542e6eeb308678367b53381bff984c31Craig Mautner firstStack.mStackBox = mFirst; 225967212cb542e6eeb308678367b53381bff984c31Craig Mautner mFirst.mStack = firstStack; 226967212cb542e6eeb308678367b53381bff984c31Craig Mautner 22705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mSecond = new StackBox(mService, mDisplayContent, this); 228967212cb542e6eeb308678367b53381bff984c31Craig Mautner secondStack.mStackBox = mSecond; 229967212cb542e6eeb308678367b53381bff984c31Craig Mautner mSecond.mStack = secondStack; 230967212cb542e6eeb308678367b53381bff984c31Craig Mautner 231967212cb542e6eeb308678367b53381bff984c31Craig Mautner mStack = null; 232967212cb542e6eeb308678367b53381bff984c31Craig Mautner return stack; 233c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 234c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 23500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Return the stackId of the first mFirst StackBox with a non-null mStack */ 23600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner int getStackId() { 23700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner if (mStack != null) { 23800af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner return mStack.mStackId; 239c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 24000af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner return mFirst.getStackId(); 241c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 242c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 24300af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner /** Remove this box and propagate its sibling's content up to their parent. 24400af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner * @return The first stackId of the resulting StackBox. */ 2454cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner int remove() { 2464cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner mDisplayContent.layoutNeeded = true; 2474cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner 2489e4f28cfa157fff89e42859edc9cce546508491fCraig Mautner if (mParent == null) { 2494cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner // This is the top-plane stack. 250a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing top plane."); 2519e4f28cfa157fff89e42859edc9cce546508491fCraig Mautner mDisplayContent.removeStackBox(this); 2529e4f28cfa157fff89e42859edc9cce546508491fCraig Mautner return HOME_STACK_ID; 2539e4f28cfa157fff89e42859edc9cce546508491fCraig Mautner } 2544cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner 2554cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner StackBox sibling = isFirstChild() ? mParent.mSecond : mParent.mFirst; 2564cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner StackBox grandparent = mParent.mParent; 257a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner sibling.mParent = grandparent; 2584cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner if (grandparent == null) { 2594cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner // mParent is a top-plane stack. Now sibling will be. 260a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent null"); 2614cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner mDisplayContent.removeStackBox(mParent); 2624cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner mDisplayContent.addStackBox(sibling, true); 26300af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner } else { 264a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent getting sibling"); 2654cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner if (mParent.isFirstChild()) { 2664cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner grandparent.mFirst = sibling; 2674cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner } else { 2684cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner grandparent.mSecond = sibling; 2694cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner } 270c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 2714cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner return sibling.getStackId(); 272c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 273c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner 2745a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner boolean resize(int stackBoxId, float weight) { 2755a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner if (mStackBoxId != stackBoxId) { 2765a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner return mStack == null && 2775a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner (mFirst.resize(stackBoxId, weight) || mSecond.resize(stackBoxId, weight)); 278967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 2795a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner // Don't change weight on topmost stack. 2805a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner if (mParent != null) { 2814cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner mParent.mWeight = isFirstChild() ? weight : 1.0f - weight; 282967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 2835a449154d1795abe8e44b7bfe821d640b145e2c6Craig Mautner return true; 284c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner } 28500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner 286967212cb542e6eeb308678367b53381bff984c31Craig Mautner /** If this is a terminal StackBox (contains a TaskStack) set the bounds. 287967212cb542e6eeb308678367b53381bff984c31Craig Mautner * @param bounds The rectangle to set the bounds to. 288d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner * @param underStatusBar True if the StackBox is directly below the Status Bar. 289967212cb542e6eeb308678367b53381bff984c31Craig Mautner * @return True if the bounds changed, false otherwise. */ 290d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner boolean setStackBoxSizes(Rect bounds, boolean underStatusBar) { 291d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner boolean change = false; 292d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner if (mUnderStatusBar != underStatusBar) { 293d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner change = true; 294d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner mUnderStatusBar = underStatusBar; 295d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner } 296967212cb542e6eeb308678367b53381bff984c31Craig Mautner if (mStack != null) { 297d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner change |= !mBounds.equals(bounds); 298b3b36ba13895d779159799341d432f6380a0ba8aCraig Mautner if (change) { 299b3b36ba13895d779159799341d432f6380a0ba8aCraig Mautner mBounds.set(bounds); 300d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner mStack.setBounds(bounds, underStatusBar); 301b3b36ba13895d779159799341d432f6380a0ba8aCraig Mautner } 302967212cb542e6eeb308678367b53381bff984c31Craig Mautner } else { 303967212cb542e6eeb308678367b53381bff984c31Craig Mautner mTmpRect.set(bounds); 304967212cb542e6eeb308678367b53381bff984c31Craig Mautner if (mVertical) { 305967212cb542e6eeb308678367b53381bff984c31Craig Mautner final int height = bounds.height(); 306967212cb542e6eeb308678367b53381bff984c31Craig Mautner int firstHeight = (int)(height * mWeight); 307967212cb542e6eeb308678367b53381bff984c31Craig Mautner mTmpRect.bottom = bounds.top + firstHeight; 308d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar); 309967212cb542e6eeb308678367b53381bff984c31Craig Mautner mTmpRect.top = mTmpRect.bottom; 310967212cb542e6eeb308678367b53381bff984c31Craig Mautner mTmpRect.bottom = bounds.top + height; 311d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner change |= mSecond.setStackBoxSizes(mTmpRect, false); 312967212cb542e6eeb308678367b53381bff984c31Craig Mautner } else { 313967212cb542e6eeb308678367b53381bff984c31Craig Mautner final int width = bounds.width(); 314967212cb542e6eeb308678367b53381bff984c31Craig Mautner int firstWidth = (int)(width * mWeight); 315967212cb542e6eeb308678367b53381bff984c31Craig Mautner mTmpRect.right = bounds.left + firstWidth; 316d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar); 317967212cb542e6eeb308678367b53381bff984c31Craig Mautner mTmpRect.left = mTmpRect.right; 318967212cb542e6eeb308678367b53381bff984c31Craig Mautner mTmpRect.right = bounds.left + width; 319d76dcdcd98f1010b9439746314629cf7cba4df89Craig Mautner change |= mSecond.setStackBoxSizes(mTmpRect, underStatusBar); 320967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 321967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 322967212cb542e6eeb308678367b53381bff984c31Craig Mautner return change; 323967212cb542e6eeb308678367b53381bff984c31Craig Mautner } 324967212cb542e6eeb308678367b53381bff984c31Craig Mautner 32505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner void resetAnimationBackgroundAnimator() { 32605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner if (mStack != null) { 32705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mStack.resetAnimationBackgroundAnimator(); 32805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return; 32905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 33005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mFirst.resetAnimationBackgroundAnimator(); 33105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mSecond.resetAnimationBackgroundAnimator(); 33205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 33305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner 33405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner boolean animateDimLayers() { 33505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner if (mStack != null) { 33605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return mStack.animateDimLayers(); 33705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 33805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner boolean result = mFirst.animateDimLayers(); 33905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner result |= mSecond.animateDimLayers(); 34005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return result; 34105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 34205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner 34305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner void resetDimming() { 34405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner if (mStack != null) { 34505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mStack.resetDimmingTag(); 34605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return; 34705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 34805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mFirst.resetDimming(); 34905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mSecond.resetDimming(); 35005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 35105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner 35205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner boolean isDimming() { 35305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner if (mStack != null) { 35405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return mStack.isDimming(); 35505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 35605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner boolean result = mFirst.isDimming(); 35705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner result |= mSecond.isDimming(); 35805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return result; 35905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 36005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner 36105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner void stopDimmingIfNeeded() { 36205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner if (mStack != null) { 36305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mStack.stopDimmingIfNeeded(); 36405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner return; 36505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 36605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mFirst.stopDimmingIfNeeded(); 36705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner mSecond.stopDimmingIfNeeded(); 36805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner } 36905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner 370ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner void switchUserStacks(int userId) { 371ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner if (mStack != null) { 372ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner mStack.switchUser(userId); 373ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner return; 374ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner } 375ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner mFirst.switchUserStacks(userId); 376ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner mSecond.switchUserStacks(userId); 377ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner } 378ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner 3792eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner void close() { 3802eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner if (mStack != null) { 3812eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner mStack.mDimLayer.mDimSurface.destroy(); 3822eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner mStack.mAnimationBackgroundSurface.mDimSurface.destroy(); 3832eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner return; 3842eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner } 3852eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner mFirst.close(); 3862eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner mSecond.close(); 3872eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner } 3882eb15342be5b075dda3df29b2b014a92ce13a5f8Craig Mautner 38900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner public void dump(String prefix, PrintWriter pw) { 39000af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner pw.print(prefix); pw.print("mParent="); pw.println(mParent); 39100af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner pw.print(prefix); pw.print("mBounds="); pw.print(mBounds.toShortString()); 3929e4f28cfa157fff89e42859edc9cce546508491fCraig Mautner pw.print(" mVertical="); pw.print(mVertical); 3939e4f28cfa157fff89e42859edc9cce546508491fCraig Mautner pw.print(" layoutNeeded="); pw.println(layoutNeeded); 394de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner if (mFirst != null) { 395967212cb542e6eeb308678367b53381bff984c31Craig Mautner pw.print(prefix); pw.print("mFirst="); pw.println(System.identityHashCode(mFirst)); 39600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner mFirst.dump(prefix + " ", pw); 397967212cb542e6eeb308678367b53381bff984c31Craig Mautner pw.print(prefix); pw.print("mSecond="); pw.println(System.identityHashCode(mSecond)); 39800af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner mSecond.dump(prefix + " ", pw); 399de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner } else { 400de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner pw.print(prefix); pw.print("mStack="); pw.println(mStack); 401de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner mStack.dump(prefix + " ", pw); 402de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner } 403de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner } 404de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner 405de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner @Override 406de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner public String toString() { 407de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner if (mStack != null) { 408de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner return "Box{" + hashCode() + " stack=" + mStack.mStackId + "}"; 40900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner } 410967212cb542e6eeb308678367b53381bff984c31Craig Mautner return "Box{" + hashCode() + " parent=" + System.identityHashCode(mParent) 411967212cb542e6eeb308678367b53381bff984c31Craig Mautner + " first=" + System.identityHashCode(mFirst) 412967212cb542e6eeb308678367b53381bff984c31Craig Mautner + " second=" + System.identityHashCode(mSecond) + "}"; 41300af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner } 414c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner} 415