blob: 72a834315b5db46805755a51d8ce77834eb75e95 [file] [log] [blame]
Craig Mautnerb1fd65c02013-02-05 13:34:57 -08001/*
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
Wale Ogunwale3797c222015-10-27 14:21:58 -070019import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
20import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
21import static android.app.ActivityManager.StackId.HOME_STACK_ID;
Chong Zhangb15758a2015-11-17 12:12:03 -080022import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
Wale Ogunwale1ed0d892015-09-28 13:27:44 -070023import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080024import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
Wale Ogunwale1ed0d892015-09-28 13:27:44 -070027import static com.android.server.wm.WindowManagerService.H.RESIZE_TASK;
Chong Zhangc806d902015-11-30 09:44:27 -080028import static com.android.server.wm.WindowManagerService.H.SHOW_NON_RESIZEABLE_DOCK_TOAST;
29import static android.view.WindowManager.DOCKED_INVALID;
30import static android.view.WindowManager.DOCKED_LEFT;
31import static android.view.WindowManager.DOCKED_RIGHT;
32import static android.view.WindowManager.DOCKED_TOP;
Wale Ogunwale99db1862015-10-23 20:08:22 -070033
Wale Ogunwale3797c222015-10-27 14:21:58 -070034import android.app.ActivityManager.StackId;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070035import android.content.res.Configuration;
36import android.graphics.Rect;
Craig Mautner2c2549c2013-11-12 08:31:15 -080037import android.util.EventLog;
Craig Mautner42bf39e2014-02-21 16:46:22 -080038import android.util.Slog;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070039import android.view.DisplayInfo;
40import android.view.Surface;
41
Craig Mautnere3119b72015-01-20 15:02:36 -080042import com.android.server.EventLogTags;
Craig Mautner2c2549c2013-11-12 08:31:15 -080043
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070044import java.io.PrintWriter;
45import java.util.ArrayList;
46
47class Task implements DimLayer.DimLayerUser {
Wale Ogunwale2cc92f52015-09-09 13:12:10 -070048 // Return value from {@link setBounds} indicating no change was made to the Task bounds.
49 static final int BOUNDS_CHANGE_NONE = 0;
50 // Return value from {@link setBounds} indicating the position of the Task bounds changed.
51 static final int BOUNDS_CHANGE_POSITION = 1;
52 // Return value from {@link setBounds} indicating the size of the Task bounds changed.
53 static final int BOUNDS_CHANGE_SIZE = 1 << 1;
54
Craig Mautnerc00204b2013-03-05 15:02:14 -080055 TaskStack mStack;
Craig Mautner05d6272ba2013-02-11 09:39:27 -080056 final AppTokenList mAppTokens = new AppTokenList();
Craig Mautner83162a92015-01-26 14:43:30 -080057 final int mTaskId;
Craig Mautnerac6f8432013-07-17 13:24:59 -070058 final int mUserId;
Craig Mautner9ef471f2014-02-07 13:11:47 -080059 boolean mDeferRemoval = false;
Craig Mautnere3119b72015-01-20 15:02:36 -080060 final WindowManagerService mService;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080061
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070062 // Content limits relative to the DisplayContent this sits in.
63 private Rect mBounds = new Rect();
64
65 // Device rotation as of the last time {@link #mBounds} was set.
66 int mRotation;
67
68 // Whether mBounds is fullscreen
69 private boolean mFullscreen = true;
70
71 // Contains configurations settings that are different from the global configuration due to
72 // stack specific operations. E.g. {@link #setBounds}.
73 Configuration mOverrideConfig;
74
75 // For comparison with DisplayContent bounds.
76 private Rect mTmpRect = new Rect();
77 // For handling display rotations.
78 private Rect mTmpRect2 = new Rect();
79
Chong Zhangb15758a2015-11-17 12:12:03 -080080 // Whether the task is resizeable
81 private boolean mResizeable;
82
Chong Zhangc806d902015-11-30 09:44:27 -080083 // Whether we need to show toast about the app being non-resizeable when it becomes visible.
84 // This flag is set when a non-resizeable task is docked (or side-by-side). It's cleared
85 // after we show the toast.
86 private boolean mShowNonResizeableDockToast;
87
Chong Zhang3005e752015-09-18 18:46:28 -070088 // Whether the task is currently being drag-resized
89 private boolean mDragResizing;
90
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070091 Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
92 Configuration config) {
Craig Mautner83162a92015-01-26 14:43:30 -080093 mTaskId = taskId;
Craig Mautnerc00204b2013-03-05 15:02:14 -080094 mStack = stack;
Craig Mautnerac6f8432013-07-17 13:24:59 -070095 mUserId = userId;
Craig Mautnere3119b72015-01-20 15:02:36 -080096 mService = service;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070097 setBounds(bounds, config);
Craig Mautnerc00204b2013-03-05 15:02:14 -080098 }
99
100 DisplayContent getDisplayContent() {
101 return mStack.getDisplayContent();
102 }
103
Chong Zhangc806d902015-11-30 09:44:27 -0800104 void setShowNonResizeableDockToast() {
105 mShowNonResizeableDockToast = true;
106 }
107
108 void scheduleShowNonResizeableDockToastIfNeeded() {
109 if (!mShowNonResizeableDockToast) {
110 return;
111 }
112 final DisplayContent displayContent = mStack.getDisplayContent();
113 // If docked stack is not yet visible, we don't want to show the toast yet,
114 // since we need the visible rect of the docked task to position the toast.
115 if (displayContent == null || displayContent.getDockedStackLocked() == null) {
116 return;
117 }
118
119 mShowNonResizeableDockToast = false;
120
121 final int dockSide = mStack.getDockSide();
122 int xOffset = 0;
123 int yOffset = 0;
124 if (dockSide != DOCKED_INVALID) {
125 mStack.getBounds(mTmpRect);
126 displayContent.getLogicalDisplayRect(mTmpRect2);
127
128 if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
129 xOffset = mTmpRect.centerX() - mTmpRect2.centerX();
130 } else if (dockSide == DOCKED_TOP) {
131 // We don't adjust for DOCKED_BOTTOM case since it's already at the bottom.
132 yOffset = mTmpRect2.bottom - mTmpRect.bottom;
133 }
134 mService.mH.obtainMessage(
135 SHOW_NON_RESIZEABLE_DOCK_TOAST, xOffset, yOffset).sendToTarget();
136 }
137 }
138
Craig Mautnerc00204b2013-03-05 15:02:14 -0800139 void addAppToken(int addPos, AppWindowToken wtoken) {
Craig Mautner42bf39e2014-02-21 16:46:22 -0800140 final int lastPos = mAppTokens.size();
Craig Mautner83162a92015-01-26 14:43:30 -0800141 if (addPos >= lastPos) {
142 addPos = lastPos;
143 } else {
144 for (int pos = 0; pos < lastPos && pos < addPos; ++pos) {
145 if (mAppTokens.get(pos).removed) {
146 // addPos assumes removed tokens are actually gone.
147 ++addPos;
148 }
Craig Mautner01f79cf2014-08-27 09:56:02 -0700149 }
Craig Mautner42bf39e2014-02-21 16:46:22 -0800150 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800151 mAppTokens.add(addPos, wtoken);
Craig Mautner83162a92015-01-26 14:43:30 -0800152 wtoken.mTask = this;
Craig Mautner42bf39e2014-02-21 16:46:22 -0800153 mDeferRemoval = false;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800154 }
155
Craig Mautnere3119b72015-01-20 15:02:36 -0800156 void removeLocked() {
157 if (!mAppTokens.isEmpty() && mStack.isAnimating()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800158 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: deferring removing taskId=" + mTaskId);
Craig Mautnere3119b72015-01-20 15:02:36 -0800159 mDeferRemoval = true;
160 return;
161 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800162 if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: removing taskId=" + mTaskId);
Craig Mautner83162a92015-01-26 14:43:30 -0800163 EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "removeTask");
Craig Mautnere3119b72015-01-20 15:02:36 -0800164 mDeferRemoval = false;
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700165 DisplayContent content = getDisplayContent();
166 if (content != null) {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800167 content.mDimLayerController.removeDimLayerUser(this);
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700168 }
Craig Mautnere3119b72015-01-20 15:02:36 -0800169 mStack.removeTask(this);
Craig Mautner83162a92015-01-26 14:43:30 -0800170 mService.mTaskIdToTask.delete(mTaskId);
Craig Mautnere3119b72015-01-20 15:02:36 -0800171 }
172
Wale Ogunwale53a29a92015-02-23 15:42:52 -0800173 void moveTaskToStack(TaskStack stack, boolean toTop) {
174 if (stack == mStack) {
175 return;
176 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800177 if (DEBUG_STACK) Slog.i(TAG_WM, "moveTaskToStack: removing taskId=" + mTaskId
Wale Ogunwale53a29a92015-02-23 15:42:52 -0800178 + " from stack=" + mStack);
Wale Ogunwale000957c2015-04-03 08:19:12 -0700179 EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "moveTask");
Wale Ogunwale53a29a92015-02-23 15:42:52 -0800180 if (mStack != null) {
181 mStack.removeTask(this);
182 }
183 stack.addTask(this, toTop);
184 }
185
Wale Ogunwale935e5022015-11-10 12:36:10 -0800186 void positionTaskInStack(TaskStack stack, int position, Rect bounds, Configuration config) {
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700187 if (mStack != null && stack != mStack) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800188 if (DEBUG_STACK) Slog.i(TAG_WM, "positionTaskInStack: removing taskId=" + mTaskId
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700189 + " from stack=" + mStack);
190 EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "moveTask");
191 mStack.removeTask(this);
192 }
193 stack.positionTask(this, position, showForAllUsers());
Wale Ogunwale935e5022015-11-10 12:36:10 -0800194 setBounds(bounds, config);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700195 }
196
Craig Mautnerc00204b2013-03-05 15:02:14 -0800197 boolean removeAppToken(AppWindowToken wtoken) {
Craig Mautner42bf39e2014-02-21 16:46:22 -0800198 boolean removed = mAppTokens.remove(wtoken);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800199 if (mAppTokens.size() == 0) {
Wale Ogunwale000957c2015-04-03 08:19:12 -0700200 EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId,
Craig Mautner2c2549c2013-11-12 08:31:15 -0800201 "removeAppToken: last token");
Craig Mautnere3119b72015-01-20 15:02:36 -0800202 if (mDeferRemoval) {
203 removeLocked();
204 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800205 }
Craig Mautner83162a92015-01-26 14:43:30 -0800206 wtoken.mTask = null;
207 /* Leave mTaskId for now, it might be useful for debug
208 wtoken.mTaskId = -1;
209 */
Craig Mautner42bf39e2014-02-21 16:46:22 -0800210 return removed;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800211 }
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800212
Craig Mautnercbd84af2014-10-22 13:21:22 -0700213 void setSendingToBottom(boolean toBottom) {
214 for (int appTokenNdx = 0; appTokenNdx < mAppTokens.size(); appTokenNdx++) {
215 mAppTokens.get(appTokenNdx).sendingToBottom = toBottom;
216 }
217 }
218
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700219 /** Set the task bounds. Passing in null sets the bounds to fullscreen. */
Wale Ogunwale2cc92f52015-09-09 13:12:10 -0700220 int setBounds(Rect bounds, Configuration config) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700221 if (config == null) {
222 config = Configuration.EMPTY;
223 }
224 if (bounds == null && !Configuration.EMPTY.equals(config)) {
225 throw new IllegalArgumentException("null bounds but non empty configuration: "
226 + config);
227 }
228 if (bounds != null && Configuration.EMPTY.equals(config)) {
229 throw new IllegalArgumentException("non null bounds, but empty configuration");
230 }
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700231 boolean oldFullscreen = mFullscreen;
232 int rotation = Surface.ROTATION_0;
233 final DisplayContent displayContent = mStack.getDisplayContent();
234 if (displayContent != null) {
235 displayContent.getLogicalDisplayRect(mTmpRect);
236 rotation = displayContent.getDisplayInfo().rotation;
237 if (bounds == null) {
238 bounds = mTmpRect;
239 mFullscreen = true;
240 } else {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700241 mFullscreen = mTmpRect.equals(bounds);
242 }
243 }
244
245 if (bounds == null) {
246 // Can't set to fullscreen if we don't have a display to get bounds from...
Wale Ogunwale2cc92f52015-09-09 13:12:10 -0700247 return BOUNDS_CHANGE_NONE;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700248 }
249 if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
Wale Ogunwale2cc92f52015-09-09 13:12:10 -0700250 return BOUNDS_CHANGE_NONE;
251 }
252
253 int boundsChange = BOUNDS_CHANGE_NONE;
Chong Zhang48a87a52015-12-03 15:36:21 -0800254 if (mBounds.left != bounds.left || mBounds.top != bounds.top) {
Wale Ogunwale2cc92f52015-09-09 13:12:10 -0700255 boundsChange |= BOUNDS_CHANGE_POSITION;
256 }
257 if (mBounds.width() != bounds.width() || mBounds.height() != bounds.height()) {
258 boundsChange |= BOUNDS_CHANGE_SIZE;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700259 }
260
261 mBounds.set(bounds);
262 mRotation = rotation;
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700263 if (displayContent != null) {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800264 displayContent.mDimLayerController.updateDimLayer(this);
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700265 }
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700266 mOverrideConfig = mFullscreen ? Configuration.EMPTY : config;
Wale Ogunwale2cc92f52015-09-09 13:12:10 -0700267 return boundsChange;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700268 }
269
Chong Zhangb15758a2015-11-17 12:12:03 -0800270 void setResizeable(boolean resizeable) {
271 mResizeable = resizeable;
272 }
273
274 boolean isResizeable() {
275 return mResizeable;
276 }
277
Chong Zhang87b21722015-09-21 15:39:51 -0700278 boolean resizeLocked(Rect bounds, Configuration configuration, boolean forced) {
Chong Zhang3005e752015-09-18 18:46:28 -0700279 int boundsChanged = setBounds(bounds, configuration);
Chong Zhang87b21722015-09-21 15:39:51 -0700280 if (forced) {
Chong Zhang3005e752015-09-18 18:46:28 -0700281 boundsChanged |= BOUNDS_CHANGE_SIZE;
Chong Zhang3005e752015-09-18 18:46:28 -0700282 }
283 if (boundsChanged == BOUNDS_CHANGE_NONE) {
284 return false;
285 }
286 if ((boundsChanged & BOUNDS_CHANGE_SIZE) == BOUNDS_CHANGE_SIZE) {
287 resizeWindows();
288 }
289 return true;
290 }
291
Chong Zhangb15758a2015-11-17 12:12:03 -0800292 boolean scrollLocked(Rect bounds) {
293 // shift the task bound if it doesn't fully cover the stack area
294 mStack.getDimBounds(mTmpRect);
295 if (mService.mCurConfiguration.orientation == ORIENTATION_LANDSCAPE) {
296 if (bounds.left > mTmpRect.left) {
297 bounds.left = mTmpRect.left;
298 bounds.right = mTmpRect.left + mBounds.width();
299 } else if (bounds.right < mTmpRect.right) {
300 bounds.left = mTmpRect.right - mBounds.width();
301 bounds.right = mTmpRect.right;
302 }
303 } else {
304 if (bounds.top > mTmpRect.top) {
305 bounds.top = mTmpRect.top;
306 bounds.bottom = mTmpRect.top + mBounds.height();
307 } else if (bounds.bottom < mTmpRect.bottom) {
308 bounds.top = mTmpRect.bottom - mBounds.height();
309 bounds.bottom = mTmpRect.bottom;
310 }
311 }
312
313 if (bounds.equals(mBounds)) {
314 return false;
315 }
316 // Normal setBounds() does not allow non-null bounds for fullscreen apps.
317 // We only change bounds for the scrolling case without change it size,
318 // on resizing path we should still want the validation.
319 mBounds.set(bounds);
320 for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
321 final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
322 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
323 final WindowState win = windows.get(winNdx);
324 win.mXOffset = bounds.left;
325 win.mYOffset = bounds.top;
326 }
327 }
328 return true;
329 }
330
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700331 /** Return true if the current bound can get outputted to the rest of the system as-is. */
332 private boolean useCurrentBounds() {
333 final DisplayContent displayContent = mStack.getDisplayContent();
334 if (mFullscreen
Wale Ogunwale3797c222015-10-27 14:21:58 -0700335 || !StackId.isTaskResizeableByDockedStack(mStack.mStackId)
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700336 || displayContent == null
337 || displayContent.getDockedStackLocked() != null) {
338 return true;
339 }
340 return false;
341 }
342
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800343 /** Original bounds of the task if applicable, otherwise fullscreen rect. */
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700344 public void getBounds(Rect out) {
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700345 if (useCurrentBounds()) {
346 // No need to adjust the output bounds if fullscreen or the docked stack is visible
347 // since it is already what we want to represent to the rest of the system.
348 out.set(mBounds);
349 return;
350 }
351
352 // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
353 // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
354 // system.
355 mStack.getDisplayContent().getLogicalDisplayRect(out);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700356 }
357
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800358
359 /**
360 * Calculate the maximum visible area of this task. If the task has only one app,
361 * the result will be visible frame of that app. If the task has more than one apps,
362 * we search from top down if the next app got different visible area.
363 *
364 * This effort is to handle the case where some task (eg. GMail composer) might pop up
365 * a dialog that's different in size from the activity below, in which case we should
366 * be dimming the entire task area behind the dialog.
367 *
368 * @param out Rect containing the max visible bounds.
369 * @return true if the task has some visible app windows; false otherwise.
370 */
371 boolean getMaxVisibleBounds(Rect out) {
372 boolean foundTop = false;
373 for (int i = mAppTokens.size() - 1; i >= 0; i--) {
Chong Zhangd8ceb852015-11-11 14:53:41 -0800374 final AppWindowToken token = mAppTokens.get(i);
375 // skip hidden (or about to hide) apps
376 if (token.mIsExiting || token.clientHidden || token.hiddenRequested) {
377 continue;
378 }
379 final WindowState win = token.findMainWindow();
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800380 if (win == null) {
381 continue;
382 }
383 if (!foundTop) {
384 out.set(win.mVisibleFrame);
385 foundTop = true;
386 continue;
387 }
388 if (win.mVisibleFrame.left < out.left) {
389 out.left = win.mVisibleFrame.left;
390 }
391 if (win.mVisibleFrame.top < out.top) {
392 out.top = win.mVisibleFrame.top;
393 }
394 if (win.mVisibleFrame.right > out.right) {
395 out.right = win.mVisibleFrame.right;
396 }
397 if (win.mVisibleFrame.bottom > out.bottom) {
398 out.bottom = win.mVisibleFrame.bottom;
399 }
400 }
401 return foundTop;
402 }
403
404 /** Bounds of the task to be used for dimming, as well as touch related tests. */
405 @Override
406 public void getDimBounds(Rect out) {
407 if (useCurrentBounds()) {
408 if (inFreeformWorkspace() && getMaxVisibleBounds(out)) {
409 return;
410 }
411
412 out.set(mBounds);
413 return;
414 }
415
416 // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
417 // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
418 // system.
419 mStack.getDisplayContent().getLogicalDisplayRect(out);
420 }
421
Chong Zhang3005e752015-09-18 18:46:28 -0700422 void setDragResizing(boolean dragResizing) {
Chong Zhang3005e752015-09-18 18:46:28 -0700423 mDragResizing = dragResizing;
424 }
425
426 boolean isDragResizing() {
427 return mDragResizing;
428 }
429
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700430 void updateDisplayInfo(final DisplayContent displayContent) {
431 if (displayContent == null) {
432 return;
433 }
434 if (mFullscreen) {
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700435 setBounds(null, Configuration.EMPTY);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700436 return;
437 }
438 final int newRotation = displayContent.getDisplayInfo().rotation;
439 if (mRotation == newRotation) {
440 return;
441 }
442
443 // Device rotation changed. We don't want the task to move around on the screen when
444 // this happens, so update the task bounds so it stays in the same place.
Wale Ogunwale94744212015-09-21 19:01:47 -0700445 mTmpRect2.set(mBounds);
446 displayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
Wale Ogunwale1ed0d892015-09-28 13:27:44 -0700447 if (setBounds(mTmpRect2, mOverrideConfig) != BOUNDS_CHANGE_NONE) {
448 // Post message to inform activity manager of the bounds change simulating
449 // a one-way call. We do this to prevent a deadlock between window manager
Filip Gruszczynski44bc4da2015-10-03 13:59:49 -0700450 // lock and activity manager lock been held. Only tasks within the freeform stack
451 // are resizeable independently of their stack resizing.
452 if (mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
453 mService.mH.sendMessage(mService.mH.obtainMessage(
454 RESIZE_TASK, mTaskId, RESIZE_MODE_SYSTEM_SCREEN_ROTATION, mBounds));
455 }
Wale Ogunwale1ed0d892015-09-28 13:27:44 -0700456 }
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700457 }
458
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700459 void resizeWindows() {
460 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
461 for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
462 final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
463 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
464 final WindowState win = windows.get(winNdx);
465 if (!resizingWindows.contains(win)) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800466 if (DEBUG_RESIZE) Slog.d(TAG_WM, "setBounds: Resizing " + win);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700467 resizingWindows.add(win);
468 }
469 }
470 }
471 }
472
Winsonc28098f2015-10-30 14:50:19 -0700473 /**
474 * Cancels any running app transitions associated with the task.
475 */
476 void cancelTaskWindowTransition() {
477 for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
478 mAppTokens.get(activityNdx).mAppAnimator.clearAnimation();
479 }
480 }
481
Winson13d30662015-11-06 15:30:29 -0800482 /**
483 * Cancels any running thumbnail transitions associated with the task.
484 */
485 void cancelTaskThumbnailTransition() {
486 for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
487 mAppTokens.get(activityNdx).mAppAnimator.clearThumbnail();
488 }
489 }
490
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700491 boolean showForAllUsers() {
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700492 final int tokensCount = mAppTokens.size();
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700493 return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700494 }
495
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700496 boolean inHomeStack() {
497 return mStack != null && mStack.mStackId == HOME_STACK_ID;
498 }
499
Chong Zhang09b21ef2015-09-14 10:20:21 -0700500 boolean inFreeformWorkspace() {
501 return mStack != null && mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
502 }
503
Filip Gruszczynski955b2fc2015-10-15 14:46:07 -0700504 boolean inDockedWorkspace() {
505 return mStack != null && mStack.mStackId == DOCKED_STACK_ID;
506 }
507
Chong Zhangb15758a2015-11-17 12:12:03 -0800508 boolean isResizeableByDockedStack() {
509 return mStack != null && getDisplayContent().getDockedStackLocked() != null &&
510 StackId.isTaskResizeableByDockedStack(mStack.mStackId);
511 }
512
513 /**
514 * Whether the task should be treated as if it's docked. Returns true if the task
515 * is currently in docked workspace, or it's side-by-side to a docked task.
516 */
517 boolean isDockedInEffect() {
518 return inDockedWorkspace() || isResizeableByDockedStack();
519 }
520
Chong Zhangd8ceb852015-11-11 14:53:41 -0800521 WindowState getTopVisibleAppMainWindow() {
522 final AppWindowToken token = getTopVisibleAppToken();
523 return token != null ? token.findMainWindow() : null;
Chong Zhang9184ec62015-09-24 12:32:21 -0700524 }
525
Chong Zhangd8ceb852015-11-11 14:53:41 -0800526 AppWindowToken getTopVisibleAppToken() {
527 for (int i = mAppTokens.size() - 1; i >= 0; i--) {
528 final AppWindowToken token = mAppTokens.get(i);
529 // skip hidden (or about to hide) apps
530 if (!token.mIsExiting && !token.clientHidden && !token.hiddenRequested) {
531 return token;
532 }
533 }
534 return null;
Chong Zhangbef461f2015-10-27 11:38:24 -0700535 }
536
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800537 @Override
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700538 public boolean isFullscreen() {
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700539 if (useCurrentBounds()) {
540 return mFullscreen;
541 }
542 // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
543 // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
544 // system.
545 return true;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700546 }
547
548 @Override
549 public DisplayInfo getDisplayInfo() {
550 return mStack.getDisplayContent().getDisplayInfo();
551 }
552
553 @Override
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800554 public String toString() {
Craig Mautner83162a92015-01-26 14:43:30 -0800555 return "{taskId=" + mTaskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}";
Craig Mautner5d9c7be2013-02-15 14:02:56 -0800556 }
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700557
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700558 @Override
559 public String toShortString() {
560 return "Task=" + mTaskId;
561 }
562
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700563 public void printTo(String prefix, PrintWriter pw) {
Wale Ogunwale56b88af2015-12-01 07:21:59 -0800564 pw.print(prefix); pw.print("taskId="); pw.println(mTaskId);
565 pw.print(prefix + prefix); pw.print("mFullscreen="); pw.println(mFullscreen);
566 pw.print(prefix + prefix); pw.print("mBounds="); pw.println(mBounds.toShortString());
567 pw.print(prefix + prefix); pw.print("mdr="); pw.println(mDeferRemoval);
568 pw.print(prefix + prefix); pw.print("appTokens="); pw.println(mAppTokens);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700569 }
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800570}