StackBox.java revision c00204b4d14d49a0417b44ca21aee4f0d4c466e0
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wm; 18 19import android.graphics.Rect; 20 21public class StackBox { 22 /** For use with {@link WindowManagerService#createStack} */ 23 public static final int TASK_STACK_GOES_BEFORE = 0; 24 public static final int TASK_STACK_GOES_AFTER = 1; 25 public static final int TASK_STACK_GOES_ABOVE = 2; 26 public static final int TASK_STACK_GOES_BELOW = 3; 27 public static final int TASK_STACK_GOES_OVER = 4; 28 public static final int TASK_STACK_GOES_UNDER = 5; 29 30 final DisplayContent mDisplayContent; 31 StackBox mParent; 32 boolean mVertical; 33 StackBox mFirst; 34 StackBox mSecond; 35 float mWeight; 36 TaskStack mStack; 37 Rect mBounds; 38 boolean layoutNeeded; 39 40 StackBox(DisplayContent displayContent, Rect bounds) { 41 mDisplayContent = displayContent; 42 mBounds = bounds; 43 } 44 45 /** Propagate #layoutNeeded bottom up. */ 46 void makeDirty() { 47 layoutNeeded = true; 48 if (mParent != null) { 49 mParent.makeDirty(); 50 } 51 } 52 53 /** Propagate #layoutNeeded top down. */ 54 void makeClean() { 55 layoutNeeded = false; 56 if (mFirst != null) { 57 mFirst.makeClean(); 58 mSecond.makeClean(); 59 } 60 } 61 62 TaskStack split(int stackId, int relativeStackId, int position, float weight) { 63 if (mStack != null) { 64 if (mStack.mStackId == relativeStackId) { 65 // Found it! 66 TaskStack stack = new TaskStack(stackId, this); 67 TaskStack firstStack; 68 TaskStack secondStack; 69 int width, height, split; 70 switch (position) { 71 default: 72 case TASK_STACK_GOES_BEFORE: 73 case TASK_STACK_GOES_AFTER: 74 mVertical = false; 75 width = (int)(weight * mBounds.width()); 76 height = mBounds.height(); 77 if (position == TASK_STACK_GOES_BEFORE) { 78 firstStack = stack; 79 secondStack = mStack; 80 split = mBounds.left + width; 81 } else { 82 firstStack = mStack; 83 secondStack = stack; 84 split = mBounds.right - width; 85 } 86 break; 87 case TASK_STACK_GOES_ABOVE: 88 case TASK_STACK_GOES_BELOW: 89 mVertical = true; 90 width = mBounds.width(); 91 height = (int)(weight * mBounds.height()); 92 if (position == TASK_STACK_GOES_ABOVE) { 93 firstStack = stack; 94 secondStack = mStack; 95 split = mBounds.top + height; 96 } else { 97 firstStack = mStack; 98 secondStack = stack; 99 split = mBounds.bottom - height; 100 } 101 break; 102 } 103 mFirst = new StackBox(mDisplayContent, new Rect(mBounds.left, mBounds.top, 104 mVertical ? mBounds.right : split, mVertical ? split : mBounds.bottom)); 105 mFirst.mStack = firstStack; 106 mSecond = new StackBox(mDisplayContent, new Rect(mVertical ? mBounds.left : split, 107 mVertical ? split : mBounds.top, mBounds.right, mBounds.bottom)); 108 mSecond.mStack = secondStack; 109 mStack = null; 110 return stack; 111 } 112 return null; 113 } 114 115 // Propagate the split to see if the target task stack is in either sub box. 116 TaskStack stack = mFirst.split(stackId, relativeStackId, position, weight); 117 if (stack != null) { 118 return stack; 119 } 120 return mSecond.split(stackId, relativeStackId, position, weight); 121 } 122 123 TaskStack merge(int position) { 124 TaskStack stack = null; 125 if (mFirst != null) { 126 switch (position) { 127 default: 128 case TASK_STACK_GOES_BEFORE: 129 case TASK_STACK_GOES_ABOVE: 130 stack = mFirst.merge(position); 131 stack.merge(mSecond.merge(position)); 132 break; 133 case TASK_STACK_GOES_AFTER: 134 case TASK_STACK_GOES_BELOW: 135 stack = mSecond.merge(position); 136 stack.merge(mFirst.merge(position)); 137 break; 138 } 139 return stack; 140 } 141 return mStack; 142 } 143 144 boolean merge(int stackId, int position, StackBox primary, StackBox secondary) { 145 TaskStack stack = primary.mStack; 146 if (stack != null && stack.mStackId == stackId) { 147 stack.merge(secondary.merge(position)); 148 mStack = stack; 149 mFirst = null; 150 mSecond = null; 151 return true; 152 } 153 return false; 154 } 155 156 boolean merge(int stackId, int position) { 157 if (mFirst != null) { 158 if (merge(stackId, position, mFirst, mSecond) 159 || merge(stackId, position, mSecond, mFirst) 160 || mFirst.merge(stackId, position) 161 || mSecond.merge(stackId, position)) { 162 return true; 163 } 164 } 165 return false; 166 } 167 168 void absorb(StackBox box) { 169 mFirst = box.mFirst; 170 mSecond = box.mSecond; 171 mStack = box.mStack; 172 layoutNeeded = true; 173 } 174 175 void removeStack() { 176 if (mParent != null) { 177 if (mParent.mFirst == this) { 178 mParent.absorb(mParent.mSecond); 179 } else { 180 mParent.absorb(mParent.mFirst); 181 } 182 mParent.makeDirty(); 183 } 184 } 185 186 boolean addTaskToStack(Task task, int stackId, boolean toTop) { 187 if (mStack != null) { 188 if (mStack.mStackId == stackId) { 189 mStack.addTask(task, toTop); 190 return true; 191 } 192 return false; 193 } 194 return mFirst.addTaskToStack(task, stackId, toTop) 195 || mSecond.addTaskToStack(task, stackId, toTop); 196 } 197 198 boolean resize(int stackId, float weight) { 199 return false; 200 } 201} 202