blob: cc7c8b0f832ddf55e79dbb9d040f3d99a8254337 [file] [log] [blame]
Craig Mautner59c00972012-07-30 12:10:24 -07001/*
2 * Copyright (C) 2012 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
Craig Mautner343ad712013-02-13 22:37:26 -080019import static com.android.server.wm.WindowManagerService.FORWARD_ITERATOR;
20import static com.android.server.wm.WindowManagerService.REVERSE_ITERATOR;
21
Dianne Hackbornc652de82013-02-15 16:32:56 -080022import android.graphics.Rect;
23import android.os.Debug;
24import android.util.Slog;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080025import android.util.SparseArray;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070026import android.view.Display;
Craig Mautner59c00972012-07-30 12:10:24 -070027import android.view.DisplayInfo;
28
29import java.io.PrintWriter;
30import java.util.ArrayList;
Craig Mautner05d6272ba2013-02-11 09:39:27 -080031import java.util.Iterator;
32import java.util.NoSuchElementException;
Craig Mautner59c00972012-07-30 12:10:24 -070033
34class DisplayContentList extends ArrayList<DisplayContent> {
35}
36
37/**
38 * Utility class for keeping track of the WindowStates and other pertinent contents of a
39 * particular Display.
40 *
41 * IMPORTANT: No method from this class should ever be used without holding
42 * WindowManagerService.mWindowMap.
43 */
44class DisplayContent {
Craig Mautner496bdbb2013-02-14 09:32:55 -080045// private final static String TAG = "DisplayContent";
Craig Mautner59c00972012-07-30 12:10:24 -070046
47 /** Unique identifier of this stack. */
48 private final int mDisplayId;
49
50 /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element
51 * from mDisplayWindows; */
52 private WindowList mWindows = new WindowList();
53
Craig Mautner59c00972012-07-30 12:10:24 -070054 // This protects the following display size properties, so that
55 // getDisplaySize() doesn't need to acquire the global lock. This is
56 // needed because the window manager sometimes needs to use ActivityThread
57 // while it has its global state locked (for example to load animation
58 // resources), but the ActivityThread also needs get the current display
59 // size sometimes when it has its package lock held.
60 //
61 // These will only be modified with both mWindowMap and mDisplaySizeLock
62 // held (in that order) so the window manager doesn't need to acquire this
63 // lock when needing these values in its normal operation.
64 final Object mDisplaySizeLock = new Object();
65 int mInitialDisplayWidth = 0;
66 int mInitialDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -070067 int mInitialDisplayDensity = 0;
Craig Mautner59c00972012-07-30 12:10:24 -070068 int mBaseDisplayWidth = 0;
69 int mBaseDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -070070 int mBaseDisplayDensity = 0;
Craig Mautner2d5618c2012-10-18 13:55:47 -070071 private final DisplayInfo mDisplayInfo = new DisplayInfo();
72 private final Display mDisplay;
Craig Mautner59c00972012-07-30 12:10:24 -070073
Craig Mautner39834192012-09-02 07:47:24 -070074 // Accessed directly by all users.
75 boolean layoutNeeded;
Craig Mautner76a71652012-09-03 23:23:58 -070076 int pendingLayoutChanges;
Craig Mautner69b08182012-09-05 13:07:13 -070077 final boolean isDefaultDisplay;
Craig Mautner39834192012-09-02 07:47:24 -070078
Craig Mautner2d5618c2012-10-18 13:55:47 -070079 /**
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080080 * Window tokens that are in the process of exiting, but still
81 * on screen for animations.
82 */
83 final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
84
85 /**
86 * Application tokens that are in the process of exiting, but still
87 * on screen for animations.
88 */
89 final AppTokenList mExitingAppTokens = new AppTokenList();
90
91 /**
92 * Sorted most recent at top, oldest at [0].
93 */
Craig Mautner05d6272ba2013-02-11 09:39:27 -080094 ArrayList<TaskList> mTaskLists = new ArrayList<TaskList>();
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080095 SparseArray<TaskList> mTaskIdToTaskList = new SparseArray<TaskList>();
96
Craig Mautner343ad712013-02-13 22:37:26 -080097 private final AppTokenIterator mTmpAppIterator = new AppTokenIterator();
98
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080099 /**
Craig Mautner2d5618c2012-10-18 13:55:47 -0700100 * @param display May not be null.
101 */
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700102 DisplayContent(Display display) {
103 mDisplay = display;
104 mDisplayId = display.getDisplayId();
105 display.getDisplayInfo(mDisplayInfo);
Craig Mautner69b08182012-09-05 13:07:13 -0700106 isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
Craig Mautner59c00972012-07-30 12:10:24 -0700107 }
108
109 int getDisplayId() {
110 return mDisplayId;
111 }
112
113 WindowList getWindowList() {
114 return mWindows;
115 }
116
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700117 Display getDisplay() {
118 return mDisplay;
119 }
120
Craig Mautner59c00972012-07-30 12:10:24 -0700121 DisplayInfo getDisplayInfo() {
122 return mDisplayInfo;
123 }
124
Craig Mautner722285e2012-09-07 13:55:58 -0700125 public void updateDisplayInfo() {
126 mDisplay.getDisplayInfo(mDisplayInfo);
127 }
128
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800129 /**
130 * Find the location to insert a new AppWindowToken into the window-ordered app token list.
131 * @param addPos The location the token was inserted into in mAppTokens.
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800132 * @param wtoken The token to insert.
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800133 */
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800134 void addAppToken(final int addPos, final AppWindowToken wtoken) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800135 TaskList task = mTaskIdToTaskList.get(wtoken.groupId);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800136 if (task == null) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800137 task = new TaskList(wtoken, this);
138 mTaskIdToTaskList.put(wtoken.groupId, task);
139 mTaskLists.add(task);
140 } else {
141 task.mAppTokens.add(wtoken);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800142 }
143 }
144
145 void removeAppToken(final AppWindowToken wtoken) {
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800146 final int taskId = wtoken.groupId;
147 final TaskList task = mTaskIdToTaskList.get(taskId);
148 if (task != null) {
149 AppTokenList appTokens = task.mAppTokens;
150 appTokens.remove(wtoken);
151 if (appTokens.size() == 0) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800152 mTaskLists.remove(task);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800153 mTaskIdToTaskList.delete(taskId);
154 }
155 }
156 }
157
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800158 void setAppTaskId(AppWindowToken wtoken, int newTaskId) {
159 final int taskId = wtoken.groupId;
160 TaskList task = mTaskIdToTaskList.get(taskId);
161 if (task != null) {
162 AppTokenList appTokens = task.mAppTokens;
163 appTokens.remove(wtoken);
164 if (appTokens.size() == 0) {
165 mTaskIdToTaskList.delete(taskId);
166 }
167 }
168
169 task = mTaskIdToTaskList.get(newTaskId);
170 if (task == null) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800171 task = new TaskList(wtoken, this);
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800172 mTaskIdToTaskList.put(newTaskId, task);
173 } else {
174 task.mAppTokens.add(wtoken);
175 }
176
177 wtoken.groupId = newTaskId;
178 }
179
Craig Mautner343ad712013-02-13 22:37:26 -0800180 /**
181 * Return the utility iterator so we don't have to construct new iterators every time we
182 * iterate.
183 * NOTE: Do not ever nest this call or you will have a bad time!
184 * @param reverse Direction of iterator.
185 * @return The utility iterator.
186 */
187 AppTokenIterator getTmpAppIterator(boolean reverse) {
188 mTmpAppIterator.reset(reverse);
189 return mTmpAppIterator;
190 }
191
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800192 class TaskListsIterator implements Iterator<TaskList> {
193 private int mCur;
194 private boolean mReverse;
195
196 TaskListsIterator() {
197 this(false);
198 }
199
200 TaskListsIterator(boolean reverse) {
Craig Mautner343ad712013-02-13 22:37:26 -0800201 reset(reverse);
202 }
203
204 void reset(boolean reverse) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800205 mReverse = reverse;
Craig Mautner343ad712013-02-13 22:37:26 -0800206 mCur = reverse ? mTaskLists.size() - 1 : 0;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800207 }
208
209 @Override
210 public boolean hasNext() {
211 if (mReverse) {
212 return mCur >= 0;
213 }
214 return mCur < mTaskLists.size();
215 }
216
217 @Override
218 public TaskList next() {
219 if (hasNext()) {
220 TaskList taskList = mTaskLists.get(mCur);
221 mCur += (mReverse ? -1 : 1);
222 return taskList;
223 }
224 throw new NoSuchElementException();
225 }
226
227 @Override
228 public void remove() {
229 throw new IllegalArgumentException();
230 }
231 }
232
233 class AppTokenIterator implements Iterator<AppWindowToken> {
Craig Mautner343ad712013-02-13 22:37:26 -0800234 final TaskListsIterator mIterator = new TaskListsIterator();
235 boolean mReverse;
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800236 int mCur;
237 TaskList mTaskList;
238
239 public AppTokenIterator() {
Craig Mautner343ad712013-02-13 22:37:26 -0800240 this(FORWARD_ITERATOR);
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800241 }
242
243 public AppTokenIterator(boolean reverse) {
Craig Mautner343ad712013-02-13 22:37:26 -0800244 reset(reverse);
245 }
246
247 void reset(boolean reverse) {
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800248 mReverse = reverse;
Craig Mautner343ad712013-02-13 22:37:26 -0800249 mIterator.reset(reverse);
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800250 getNextTaskList();
251 }
252
253 private void getNextTaskList() {
254 if (mIterator.hasNext()) {
255 mTaskList = mIterator.next();
256 mCur = mReverse ? mTaskList.mAppTokens.size() - 1 : 0;
257 }
258 }
259
260 @Override
261 public boolean hasNext() {
262 if (mTaskList == null) {
263 return false;
264 }
265 if (mReverse) {
266 return mCur >= 0;
267 }
268 return mCur < mTaskList.mAppTokens.size();
269 }
270
271 @Override
272 public AppWindowToken next() {
273 if (hasNext()) {
274 AppWindowToken wtoken = mTaskList.mAppTokens.get(mCur);
275 mCur += mReverse ? -1 : 1;
276 if (!hasNext()) {
277 getNextTaskList();
278 }
279 return wtoken;
280 }
281 throw new NoSuchElementException();
282 }
283
284 @Override
285 public void remove() {
286 throw new IllegalArgumentException();
287 }
Craig Mautner30e2d722013-02-12 11:30:16 -0800288
289 int size() {
290 int size = 0;
291 final TaskListsIterator iterator = new TaskListsIterator();
292 while (iterator.hasNext()) {
293 size += iterator.next().mAppTokens.size();
294 }
295 return size;
296 }
Craig Mautner05d6272ba2013-02-11 09:39:27 -0800297 }
298
Craig Mautnera91f9e22012-09-14 16:22:08 -0700299 public void dump(String prefix, PrintWriter pw) {
300 pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
301 final String subPrefix = " " + prefix;
302 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
303 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
304 pw.print("dpi");
305 if (mInitialDisplayWidth != mBaseDisplayWidth
306 || mInitialDisplayHeight != mBaseDisplayHeight
307 || mInitialDisplayDensity != mBaseDisplayDensity) {
308 pw.print(" base=");
309 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
310 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
311 }
312 pw.print(" cur=");
313 pw.print(mDisplayInfo.logicalWidth);
314 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
315 pw.print(" app=");
316 pw.print(mDisplayInfo.appWidth);
317 pw.print("x"); pw.print(mDisplayInfo.appHeight);
318 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
319 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
320 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
321 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800322 pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
Craig Mautner343ad712013-02-13 22:37:26 -0800323 AppTokenIterator iterator = getTmpAppIterator(REVERSE_ITERATOR);
Craig Mautner926f3832013-02-13 11:56:07 -0800324 int ndx = iterator.size() - 1;
325 if (ndx >= 0) {
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800326 pw.println();
327 pw.println(" Application tokens in Z order:");
Craig Mautner926f3832013-02-13 11:56:07 -0800328 while (iterator.hasNext()) {
329 AppWindowToken wtoken = iterator.next();
330 pw.print(" App #"); pw.print(ndx--);
331 pw.print(' '); pw.print(wtoken); pw.println(":");
332 wtoken.dump(pw, " ");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800333 }
334 }
335 if (mExitingTokens.size() > 0) {
336 pw.println();
337 pw.println(" Exiting tokens:");
338 for (int i=mExitingTokens.size()-1; i>=0; i--) {
339 WindowToken token = mExitingTokens.get(i);
340 pw.print(" Exiting #"); pw.print(i);
341 pw.print(' '); pw.print(token);
342 pw.println(':');
343 token.dump(pw, " ");
344 }
345 }
346 if (mExitingAppTokens.size() > 0) {
347 pw.println();
348 pw.println(" Exiting application tokens:");
349 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
350 WindowToken token = mExitingAppTokens.get(i);
351 pw.print(" Exiting App #"); pw.print(i);
352 pw.print(' '); pw.print(token);
353 pw.println(':');
354 token.dump(pw, " ");
355 }
356 }
357 if (mTaskIdToTaskList.size() > 0) {
358 pw.println();
359 for (int i = 0; i < mTaskIdToTaskList.size(); ++i) {
360 pw.print(" TaskList #"); pw.print(i);
361 pw.print(" taskId="); pw.println(mTaskIdToTaskList.keyAt(i));
362 pw.print(" mAppTokens=");
363 pw.println(mTaskIdToTaskList.valueAt(i).mAppTokens);
364 pw.println();
365 }
366 }
Craig Mautner59c00972012-07-30 12:10:24 -0700367 pw.println();
368 }
369}