blob: 7cdf8b21c9556e2adddfe1c082af161e897eb12e [file] [log] [blame]
Craig Mautnerc00204b2013-03-05 15:02:14 -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
Craig Mautnerf0ac5c82013-06-24 11:21:57 -070019import static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
20import static com.android.server.wm.WindowManagerService.TAG;
21
Wale Ogunwale60454db2015-01-23 16:05:07 -080022import android.content.res.Configuration;
Craig Mautner05d29032013-05-03 13:40:13 -070023import android.graphics.Rect;
Craig Mautnerf0ac5c82013-06-24 11:21:57 -070024import android.os.Debug;
Wale Ogunwale60454db2015-01-23 16:05:07 -080025import android.util.DisplayMetrics;
Craig Mautner2c2549c2013-11-12 08:31:15 -080026import android.util.EventLog;
Craig Mautnerf0ac5c82013-06-24 11:21:57 -070027import android.util.Slog;
Craig Mautner05d29032013-05-03 13:40:13 -070028import android.util.TypedValue;
Wale Ogunwale4a02d812015-02-12 23:01:38 -080029import android.view.Surface;
Todd Kennedyaab56db2015-01-30 09:39:53 -080030
Craig Mautner2c2549c2013-11-12 08:31:15 -080031import com.android.server.EventLogTags;
Craig Mautner05d29032013-05-03 13:40:13 -070032
Craig Mautner00af9fe2013-03-25 09:13:41 -070033import java.io.PrintWriter;
Craig Mautnerc00204b2013-03-05 15:02:14 -080034import java.util.ArrayList;
35
36public class TaskStack {
Craig Mautner05d29032013-05-03 13:40:13 -070037 /** Amount of time in milliseconds to animate the dim surface from one value to another,
38 * when no window animation is driving it. */
39 private static final int DEFAULT_DIM_DURATION = 200;
40
Craig Mautner00af9fe2013-03-25 09:13:41 -070041 /** Unique identifier */
Craig Mautnerc00204b2013-03-05 15:02:14 -080042 final int mStackId;
Craig Mautner00af9fe2013-03-25 09:13:41 -070043
Craig Mautner05d29032013-05-03 13:40:13 -070044 /** The service */
45 private final WindowManagerService mService;
46
Craig Mautner00af9fe2013-03-25 09:13:41 -070047 /** The display this stack sits under. */
Craig Mautnerdf88d732014-01-27 09:21:32 -080048 private DisplayContent mDisplayContent;
Craig Mautner00af9fe2013-03-25 09:13:41 -070049
50 /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
51 * mTaskHistory in the ActivityStack with the same mStackId */
Craig Mautner2c2549c2013-11-12 08:31:15 -080052 private final ArrayList<Task> mTasks = new ArrayList<Task>();
Craig Mautner00af9fe2013-03-25 09:13:41 -070053
Craig Mautnerb660b9d2014-02-13 10:59:16 -080054 /** For comparison with DisplayContent bounds. */
55 private Rect mTmpRect = new Rect();
Wale Ogunwale4a02d812015-02-12 23:01:38 -080056 /** For handling display rotations. */
57 private Rect mTmpRect2 = new Rect();
Craig Mautnerb660b9d2014-02-13 10:59:16 -080058
59 /** Content limits relative to the DisplayContent this sits in. */
60 private Rect mBounds = new Rect();
61
62 /** Whether mBounds is fullscreen */
63 private boolean mFullscreen = true;
Craig Mautnerc00204b2013-03-05 15:02:14 -080064
Craig Mautner05d29032013-05-03 13:40:13 -070065 /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
Craig Mautnerb660b9d2014-02-13 10:59:16 -080066 private DimLayer mDimLayer;
Craig Mautner05d29032013-05-03 13:40:13 -070067
68 /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
69 WindowStateAnimator mDimWinAnimator;
70
71 /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
Craig Mautnerdf88d732014-01-27 09:21:32 -080072 DimLayer mAnimationBackgroundSurface;
Craig Mautner05d29032013-05-03 13:40:13 -070073
74 /** The particular window with an Animation with non-zero background color. */
75 WindowStateAnimator mAnimationBackgroundAnimator;
76
77 /** Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
78 * then stop any dimming. */
79 boolean mDimmingTag;
80
Craig Mautnerdc548482014-02-05 13:35:24 -080081 /** Application tokens that are exiting, but still on screen for animations. */
82 final AppTokenList mExitingAppTokens = new AppTokenList();
83
Craig Mautner95da1082014-02-24 17:54:35 -080084 /** Detach this stack from its display when animation completes. */
85 boolean mDeferDetach;
86
Wale Ogunwale60454db2015-01-23 16:05:07 -080087 // Contains configurations settings that are different from the global configuration due to
88 // stack specific operations. E.g. {@link #setBounds}.
89 Configuration mOverrideConfig;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -080090 // True if the stack was forced to fullscreen disregarding the override configuration.
91 private boolean mForceFullscreen;
92 // The {@link #mBounds} before the stack was forced to fullscreen. Will be restored as the
93 // stack bounds once the stack is no longer forced to fullscreen.
94 final private Rect mPreForceFullscreenBounds;
Wale Ogunwale60454db2015-01-23 16:05:07 -080095
Wale Ogunwale4a02d812015-02-12 23:01:38 -080096 // Device rotation as of the last time {@link #mBounds} was set.
97 int mRotation;
98
Craig Mautnerdf88d732014-01-27 09:21:32 -080099 TaskStack(WindowManagerService service, int stackId) {
Craig Mautner05d29032013-05-03 13:40:13 -0700100 mService = service;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800101 mStackId = stackId;
Wale Ogunwale60454db2015-01-23 16:05:07 -0800102 mOverrideConfig = Configuration.EMPTY;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800103 mForceFullscreen = false;
104 mPreForceFullscreenBounds = new Rect();
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800105 // TODO: remove bounds from log, they are always 0.
106 EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
107 mBounds.right, mBounds.bottom);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800108 }
109
110 DisplayContent getDisplayContent() {
111 return mDisplayContent;
112 }
113
Craig Mautnerd9a22882013-03-16 15:00:36 -0700114 ArrayList<Task> getTasks() {
115 return mTasks;
116 }
117
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800118 void resizeWindows() {
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800119 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
120 for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
121 final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
122 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
123 final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
124 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
125 final WindowState win = windows.get(winNdx);
126 if (!resizingWindows.contains(win)) {
127 if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG,
128 "setBounds: Resizing " + win);
129 resizingWindows.add(win);
130 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800131 }
132 }
133 }
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700134 }
135
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800136 /** Set the stack bounds. Passing in null sets the bounds to fullscreen. */
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800137 boolean setBounds(Rect bounds) {
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800138 boolean oldFullscreen = mFullscreen;
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800139 int rotation = Surface.ROTATION_0;
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800140 if (mDisplayContent != null) {
141 mDisplayContent.getLogicalDisplayRect(mTmpRect);
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800142 rotation = mDisplayContent.getDisplayInfo().rotation;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800143 if (bounds == null) {
144 bounds = mTmpRect;
145 mFullscreen = true;
146 } else {
147 bounds.intersect(mTmpRect); // ensure bounds are entirely within the display rect
148 mFullscreen = mTmpRect.equals(bounds);
149 }
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800150 }
151
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800152 if (bounds == null) {
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800153 // Can't set to fullscreen if we don't have a display to get bounds from...
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800154 return false;
155 }
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800156 if (mBounds.equals(bounds) && oldFullscreen == mFullscreen && mRotation == rotation) {
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800157 return false;
158 }
159
Wale Ogunwale0ade61b2015-03-24 10:40:32 -0700160 mDimLayer.setBounds(bounds);
161 mAnimationBackgroundSurface.setBounds(bounds);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800162 mBounds.set(bounds);
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800163 mRotation = rotation;
Wale Ogunwale60454db2015-01-23 16:05:07 -0800164 updateOverrideConfiguration();
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800165 return true;
166 }
167
168 void getBounds(Rect out) {
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800169 out.set(mBounds);
170 }
171
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800172 private void updateOverrideConfiguration() {
Wale Ogunwale60454db2015-01-23 16:05:07 -0800173 final Configuration serviceConfig = mService.mCurConfiguration;
174 if (mFullscreen) {
175 mOverrideConfig = Configuration.EMPTY;
176 return;
177 }
178
179 if (mOverrideConfig == Configuration.EMPTY) {
180 mOverrideConfig = new Configuration();
181 }
182
183 // TODO(multidisplay): Update Dp to that of display stack is on.
184 final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
185 mOverrideConfig.screenWidthDp =
186 Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
187 mOverrideConfig.screenHeightDp =
188 Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
189 mOverrideConfig.smallestScreenWidthDp =
190 Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
Wale Ogunwalea9281272015-02-07 14:04:19 -0800191 mOverrideConfig.orientation =
192 (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
193 ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
Wale Ogunwale60454db2015-01-23 16:05:07 -0800194 }
195
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800196 void updateDisplayInfo() {
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800197 if (mFullscreen) {
198 setBounds(null);
199 } else if (mDisplayContent != null) {
200 final int newRotation = mDisplayContent.getDisplayInfo().rotation;
201 if (mRotation == newRotation) {
202 return;
203 }
204
205 // Device rotation changed. We don't want the stack to move around on the screen when
206 // this happens, so update the stack bounds so it stays in the same place.
207 final int rotationDelta = DisplayContent.deltaRotation(mRotation, newRotation);
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800208 mDisplayContent.getLogicalDisplayRect(mTmpRect);
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800209 switch (rotationDelta) {
210 case Surface.ROTATION_0:
211 mTmpRect2.set(mBounds);
212 break;
213 case Surface.ROTATION_90:
214 mTmpRect2.top = mTmpRect.bottom - mBounds.right;
215 mTmpRect2.left = mBounds.top;
216 mTmpRect2.right = mTmpRect2.left + mBounds.height();
217 mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
218 break;
219 case Surface.ROTATION_180:
220 mTmpRect2.top = mTmpRect.bottom - mBounds.bottom;
221 mTmpRect2.left = mTmpRect.right - mBounds.right;
222 mTmpRect2.right = mTmpRect2.left + mBounds.width();
223 mTmpRect2.bottom = mTmpRect2.top + mBounds.height();
224 break;
225 case Surface.ROTATION_270:
226 mTmpRect2.top = mBounds.left;
227 mTmpRect2.left = mTmpRect.right - mBounds.bottom;
228 mTmpRect2.right = mTmpRect2.left + mBounds.height();
229 mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
230 break;
231 }
232 setBounds(mTmpRect2);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800233 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800234 }
235
236 boolean isFullscreen() {
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800237 return mFullscreen;
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800238 }
239
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800240 /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen.
241 * Returns true if something happened.
242 */
243 boolean forceFullscreen(boolean forceFullscreen) {
244 if (mForceFullscreen == forceFullscreen) {
245 return false;
246 }
247 mForceFullscreen = forceFullscreen;
248 if (forceFullscreen) {
249 if (mFullscreen) {
250 return false;
251 }
252 mPreForceFullscreenBounds.set(mBounds);
253 return setBounds(null);
254 } else {
255 if (!mFullscreen || mPreForceFullscreenBounds.isEmpty()) {
256 return false;
257 }
258 return setBounds(mPreForceFullscreenBounds);
259 }
260 }
261
Craig Mautner1bf2b872014-02-05 15:37:40 -0800262 boolean isAnimating() {
263 for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
264 final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
265 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
266 final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
267 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
Craig Mautnerbc2a6df2014-06-13 15:08:48 -0700268 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Craig Mautner7c9ee192014-08-14 16:08:26 -0700269 if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) {
Craig Mautner1bf2b872014-02-05 15:37:40 -0800270 return true;
271 }
272 }
273 }
274 }
275 return false;
276 }
277
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700278 void addTask(Task task, boolean toTop) {
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700279 addTask(task, toTop, task.showForAllUsers());
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700280 }
281
Craig Mautner00af9fe2013-03-25 09:13:41 -0700282 /**
283 * Put a Task in this stack. Used for adding and moving.
284 * @param task The task to add.
285 * @param toTop Whether to add it to the top or bottom.
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700286 * @param showForAllUsers Whether to show the task regardless of the current user.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700287 */
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700288 void addTask(Task task, boolean toTop, boolean showForAllUsers) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700289 int stackNdx;
290 if (!toTop) {
291 stackNdx = 0;
292 } else {
293 stackNdx = mTasks.size();
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700294 if (!showForAllUsers && !mService.isCurrentProfileLocked(task.mUserId)) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700295 // Place the task below all current user tasks.
296 while (--stackNdx >= 0) {
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700297 final Task tmpTask = mTasks.get(stackNdx);
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700298 if (!tmpTask.showForAllUsers()
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700299 || !mService.isCurrentProfileLocked(tmpTask.mUserId)) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700300 break;
301 }
302 }
Craig Mautnere0d50cc2014-06-02 10:11:53 -0700303 // Put it above first non-current user task.
Craig Mautnerac6f8432013-07-17 13:24:59 -0700304 ++stackNdx;
305 }
306 }
307 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "addTask: task=" + task + " toTop=" + toTop
308 + " pos=" + stackNdx);
309 mTasks.add(stackNdx, task);
310
Craig Mautner967212c2013-04-13 21:10:58 -0700311 task.mStack = this;
raysb.kim00a27252014-11-11 08:38:21 +0900312 if (toTop) {
313 mDisplayContent.moveStack(this, true);
314 }
Craig Mautner83162a92015-01-26 14:43:30 -0800315 EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.mTaskId, toTop ? 1 : 0, stackNdx);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800316 }
317
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800318 void moveTaskToTop(Task task) {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -0700319 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
320 + Debug.getCallers(6));
Craig Mautnerd9a22882013-03-16 15:00:36 -0700321 mTasks.remove(task);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800322 addTask(task, true);
Craig Mautnerd9a22882013-03-16 15:00:36 -0700323 }
324
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800325 void moveTaskToBottom(Task task) {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -0700326 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
Craig Mautnerd9a22882013-03-16 15:00:36 -0700327 mTasks.remove(task);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800328 addTask(task, false);
Craig Mautnerd9a22882013-03-16 15:00:36 -0700329 }
330
Craig Mautner00af9fe2013-03-25 09:13:41 -0700331 /**
Craig Mautner04a0ea62014-01-13 12:51:26 -0800332 * Delete a Task from this stack. If it is the last Task in the stack, move this stack to the
333 * back.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700334 * @param task The Task to delete.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700335 */
Craig Mautnerde4ef022013-04-07 19:01:33 -0700336 void removeTask(Task task) {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -0700337 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700338 mTasks.remove(task);
Craig Mautnerdf88d732014-01-27 09:21:32 -0800339 if (mDisplayContent != null) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800340 if (mTasks.isEmpty()) {
341 mDisplayContent.moveStack(this, false);
342 }
343 mDisplayContent.layoutNeeded = true;
Craig Mautner04a0ea62014-01-13 12:51:26 -0800344 }
Craig Mautnere3119b72015-01-20 15:02:36 -0800345 for (int appNdx = mExitingAppTokens.size() - 1; appNdx >= 0; --appNdx) {
346 final AppWindowToken wtoken = mExitingAppTokens.get(appNdx);
Craig Mautner83162a92015-01-26 14:43:30 -0800347 if (wtoken.mTask == task) {
Craig Mautnere3119b72015-01-20 15:02:36 -0800348 wtoken.mIsExiting = false;
349 mExitingAppTokens.remove(appNdx);
350 }
351 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800352 }
353
Craig Mautnerdf88d732014-01-27 09:21:32 -0800354 void attachDisplayContent(DisplayContent displayContent) {
355 if (mDisplayContent != null) {
356 throw new IllegalStateException("attachDisplayContent: Already attached");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800357 }
Craig Mautnerdf88d732014-01-27 09:21:32 -0800358
359 mDisplayContent = displayContent;
360 mDimLayer = new DimLayer(mService, this, displayContent);
361 mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent);
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800362 updateDisplayInfo();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800363 }
364
Craig Mautnerdc548482014-02-05 13:35:24 -0800365 void detachDisplay() {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800366 EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
Craig Mautnerbc2a6df2014-06-13 15:08:48 -0700367
368 boolean doAnotherLayoutPass = false;
Craig Mautnerdc548482014-02-05 13:35:24 -0800369 for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
Craig Mautnerbc2a6df2014-06-13 15:08:48 -0700370 final AppTokenList appWindowTokens = mTasks.get(taskNdx).mAppTokens;
371 for (int appNdx = appWindowTokens.size() - 1; appNdx >= 0; --appNdx) {
372 final WindowList appWindows = appWindowTokens.get(appNdx).allAppWindows;
373 for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) {
Craig Mautnerb605f4a2015-02-18 13:08:42 -0800374 mService.removeWindowInnerLocked(appWindows.get(winNdx));
Craig Mautnerbc2a6df2014-06-13 15:08:48 -0700375 doAnotherLayoutPass = true;
376 }
377 }
Craig Mautnerdc548482014-02-05 13:35:24 -0800378 }
Craig Mautnerbc2a6df2014-06-13 15:08:48 -0700379 if (doAnotherLayoutPass) {
380 mService.requestTraversalLocked();
381 }
382
Craig Mautner00a66752015-03-23 14:00:47 -0700383 close();
384
Craig Mautnerdf88d732014-01-27 09:21:32 -0800385 mDisplayContent = null;
Craig Mautner00af9fe2013-03-25 09:13:41 -0700386 }
387
Craig Mautner05d29032013-05-03 13:40:13 -0700388 void resetAnimationBackgroundAnimator() {
389 mAnimationBackgroundAnimator = null;
390 mAnimationBackgroundSurface.hide();
391 }
392
393 private long getDimBehindFadeDuration(long duration) {
394 TypedValue tv = new TypedValue();
395 mService.mContext.getResources().getValue(
396 com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
397 if (tv.type == TypedValue.TYPE_FRACTION) {
398 duration = (long)tv.getFraction(duration, duration);
399 } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
400 duration = tv.data;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800401 }
Craig Mautner05d29032013-05-03 13:40:13 -0700402 return duration;
403 }
404
405 boolean animateDimLayers() {
406 final int dimLayer;
407 final float dimAmount;
408 if (mDimWinAnimator == null) {
409 dimLayer = mDimLayer.getLayer();
410 dimAmount = 0;
411 } else {
412 dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
413 dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
414 }
415 final float targetAlpha = mDimLayer.getTargetAlpha();
416 if (targetAlpha != dimAmount) {
417 if (mDimWinAnimator == null) {
418 mDimLayer.hide(DEFAULT_DIM_DURATION);
419 } else {
420 long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
421 ? mDimWinAnimator.mAnimation.computeDurationHint()
422 : DEFAULT_DIM_DURATION;
423 if (targetAlpha > dimAmount) {
424 duration = getDimBehindFadeDuration(duration);
425 }
426 mDimLayer.show(dimLayer, dimAmount, duration);
427 }
428 } else if (mDimLayer.getLayer() != dimLayer) {
429 mDimLayer.setLayer(dimLayer);
430 }
431 if (mDimLayer.isAnimating()) {
432 if (!mService.okToDisplay()) {
433 // Jump to the end of the animation.
434 mDimLayer.show();
435 } else {
436 return mDimLayer.stepAnimation();
437 }
438 }
439 return false;
440 }
441
442 void resetDimmingTag() {
443 mDimmingTag = false;
444 }
445
446 void setDimmingTag() {
447 mDimmingTag = true;
448 }
449
450 boolean testDimmingTag() {
451 return mDimmingTag;
452 }
453
454 boolean isDimming() {
455 return mDimLayer.isDimming();
456 }
457
458 boolean isDimming(WindowStateAnimator winAnimator) {
459 return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
460 }
461
462 void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
463 // Only set dim params on the highest dimmed layer.
Craig Mautner05d29032013-05-03 13:40:13 -0700464 // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800465 if (newWinAnimator.mSurfaceShown && (mDimWinAnimator == null
466 || !mDimWinAnimator.mSurfaceShown
467 || mDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
Craig Mautner05d29032013-05-03 13:40:13 -0700468 mDimWinAnimator = newWinAnimator;
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800469 if (mDimWinAnimator.mWin.mAppToken == null
470 && !mFullscreen && mDisplayContent != null) {
471 // Dim should cover the entire screen for system windows.
472 mDisplayContent.getLogicalDisplayRect(mTmpRect);
473 mDimLayer.setBounds(mTmpRect);
474 }
Craig Mautner05d29032013-05-03 13:40:13 -0700475 }
476 }
477
478 void stopDimmingIfNeeded() {
479 if (!mDimmingTag && isDimming()) {
480 mDimWinAnimator = null;
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800481 mDimLayer.setBounds(mBounds);
Craig Mautner05d29032013-05-03 13:40:13 -0700482 }
483 }
484
485 void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
486 int animLayer = winAnimator.mAnimLayer;
487 if (mAnimationBackgroundAnimator == null
488 || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
489 mAnimationBackgroundAnimator = winAnimator;
490 animLayer = mService.adjustAnimationBackground(winAnimator);
491 mAnimationBackgroundSurface.show(animLayer - WindowManagerService.LAYER_OFFSET_DIM,
492 ((color >> 24) & 0xff) / 255f, 0);
493 }
494 }
495
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800496 void switchUser() {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700497 int top = mTasks.size();
498 for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
499 Task task = mTasks.get(taskNdx);
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700500 if (mService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
Craig Mautnerac6f8432013-07-17 13:24:59 -0700501 mTasks.remove(taskNdx);
502 mTasks.add(task);
503 --top;
504 }
505 }
506 }
507
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800508 void close() {
Craig Mautner00a66752015-03-23 14:00:47 -0700509 if (mAnimationBackgroundSurface != null) {
510 mAnimationBackgroundSurface.destroySurface();
511 mAnimationBackgroundSurface = null;
512 }
513 if (mDimLayer != null) {
514 mDimLayer.destroySurface();
515 mDimLayer = null;
516 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800517 }
518
Craig Mautner00af9fe2013-03-25 09:13:41 -0700519 public void dump(String prefix, PrintWriter pw) {
520 pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
Craig Mautner95da1082014-02-24 17:54:35 -0800521 pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
Craig Mautner00af9fe2013-03-25 09:13:41 -0700522 for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
523 pw.print(prefix); pw.println(mTasks.get(taskNdx));
524 }
Craig Mautner05d29032013-05-03 13:40:13 -0700525 if (mAnimationBackgroundSurface.isDimming()) {
526 pw.print(prefix); pw.println("mWindowAnimationBackgroundSurface:");
527 mAnimationBackgroundSurface.printTo(prefix + " ", pw);
528 }
529 if (mDimLayer.isDimming()) {
530 pw.print(prefix); pw.println("mDimLayer:");
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800531 mDimLayer.printTo(prefix + " ", pw);
Craig Mautner05d29032013-05-03 13:40:13 -0700532 pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
533 }
Craig Mautnerdc548482014-02-05 13:35:24 -0800534 if (!mExitingAppTokens.isEmpty()) {
535 pw.println();
536 pw.println(" Exiting application tokens:");
537 for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
538 WindowToken token = mExitingAppTokens.get(i);
539 pw.print(" Exiting App #"); pw.print(i);
540 pw.print(' '); pw.print(token);
541 pw.println(':');
542 token.dump(pw, " ");
543 }
544 }
Craig Mautner00af9fe2013-03-25 09:13:41 -0700545 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700546
547 @Override
548 public String toString() {
549 return "{stackId=" + mStackId + " tasks=" + mTasks + "}";
550 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800551}