blob: 18019e68d85d63ca61bf0a21dcc73c00192cc318 [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
Craig Mautner05d29032013-05-03 13:40:13 -070022import android.graphics.Rect;
Craig Mautnerf0ac5c82013-06-24 11:21:57 -070023import android.os.Debug;
24import android.util.Slog;
Craig Mautner05d29032013-05-03 13:40:13 -070025import android.util.TypedValue;
26
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -070027import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
28
Craig Mautner00af9fe2013-03-25 09:13:41 -070029import java.io.PrintWriter;
Craig Mautnerc00204b2013-03-05 15:02:14 -080030import java.util.ArrayList;
31
32public class TaskStack {
Craig Mautner05d29032013-05-03 13:40:13 -070033 /** Amount of time in milliseconds to animate the dim surface from one value to another,
34 * when no window animation is driving it. */
35 private static final int DEFAULT_DIM_DURATION = 200;
36
Craig Mautner00af9fe2013-03-25 09:13:41 -070037 /** Unique identifier */
Craig Mautnerc00204b2013-03-05 15:02:14 -080038 final int mStackId;
Craig Mautner00af9fe2013-03-25 09:13:41 -070039
Craig Mautner05d29032013-05-03 13:40:13 -070040 /** The service */
41 private final WindowManagerService mService;
42
Craig Mautner00af9fe2013-03-25 09:13:41 -070043 /** The display this stack sits under. */
44 private final DisplayContent mDisplayContent;
45
46 /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
47 * mTaskHistory in the ActivityStack with the same mStackId */
Craig Mautnerc00204b2013-03-05 15:02:14 -080048 private ArrayList<Task> mTasks = new ArrayList<Task>();
Craig Mautner00af9fe2013-03-25 09:13:41 -070049
50 /** The StackBox this sits in. */
Craig Mautner967212c2013-04-13 21:10:58 -070051 StackBox mStackBox;
Craig Mautnerc00204b2013-03-05 15:02:14 -080052
Craig Mautner05d29032013-05-03 13:40:13 -070053 /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
54 final DimLayer mDimLayer;
55
56 /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
57 WindowStateAnimator mDimWinAnimator;
58
59 /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
60 final DimLayer mAnimationBackgroundSurface;
61
62 /** The particular window with an Animation with non-zero background color. */
63 WindowStateAnimator mAnimationBackgroundAnimator;
64
65 /** Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
66 * then stop any dimming. */
67 boolean mDimmingTag;
68
69 TaskStack(WindowManagerService service, int stackId, DisplayContent displayContent) {
70 mService = service;
Craig Mautnerc00204b2013-03-05 15:02:14 -080071 mStackId = stackId;
Craig Mautner967212c2013-04-13 21:10:58 -070072 mDisplayContent = displayContent;
Craig Mautner05d29032013-05-03 13:40:13 -070073 final int displayId = displayContent.getDisplayId();
74 mDimLayer = new DimLayer(service, displayId);
75 mAnimationBackgroundSurface = new DimLayer(service, displayId);
Craig Mautnerc00204b2013-03-05 15:02:14 -080076 }
77
78 DisplayContent getDisplayContent() {
79 return mDisplayContent;
80 }
81
Craig Mautnerd9a22882013-03-16 15:00:36 -070082 ArrayList<Task> getTasks() {
83 return mTasks;
84 }
85
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -070086 boolean isHomeStack() {
87 return mStackId == HOME_STACK_ID;
88 }
89
John Spurlock7045aaa2013-07-16 17:38:54 -040090 boolean hasSibling() {
91 return mStackBox.mParent != null;
92 }
93
Craig Mautner00af9fe2013-03-25 09:13:41 -070094 /**
95 * Put a Task in this stack. Used for adding and moving.
96 * @param task The task to add.
97 * @param toTop Whether to add it to the top or bottom.
98 */
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -070099 boolean addTask(Task task, boolean toTop) {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -0700100 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "addTask: task=" + task + " toTop=" + toTop);
Craig Mautner967212c2013-04-13 21:10:58 -0700101 mStackBox.makeDirty();
Craig Mautnerc00204b2013-03-05 15:02:14 -0800102 mTasks.add(toTop ? mTasks.size() : 0, task);
Craig Mautner967212c2013-04-13 21:10:58 -0700103 task.mStack = this;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700104 return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800105 }
106
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700107 boolean moveTaskToTop(Task task) {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -0700108 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
109 + Debug.getCallers(6));
Craig Mautnerd9a22882013-03-16 15:00:36 -0700110 mTasks.remove(task);
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700111 return addTask(task, true);
Craig Mautnerd9a22882013-03-16 15:00:36 -0700112 }
113
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700114 boolean moveTaskToBottom(Task task) {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -0700115 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
Craig Mautnerd9a22882013-03-16 15:00:36 -0700116 mTasks.remove(task);
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700117 return addTask(task, false);
Craig Mautnerd9a22882013-03-16 15:00:36 -0700118 }
119
Craig Mautner00af9fe2013-03-25 09:13:41 -0700120 /**
121 * Delete a Task from this stack. If it is the last Task in the stack, remove this stack from
122 * its parent StackBox and merge the parent.
123 * @param task The Task to delete.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700124 */
Craig Mautnerde4ef022013-04-07 19:01:33 -0700125 void removeTask(Task task) {
Craig Mautnerf0ac5c82013-06-24 11:21:57 -0700126 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
Craig Mautner967212c2013-04-13 21:10:58 -0700127 mStackBox.makeDirty();
Craig Mautnerde4ef022013-04-07 19:01:33 -0700128 mTasks.remove(task);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800129 }
130
Craig Mautner00af9fe2013-03-25 09:13:41 -0700131 int remove() {
Craig Mautner05d29032013-05-03 13:40:13 -0700132 mAnimationBackgroundSurface.destroySurface();
133 mDimLayer.destroySurface();
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700134 return mStackBox.remove();
Craig Mautner00af9fe2013-03-25 09:13:41 -0700135 }
136
Craig Mautner05d29032013-05-03 13:40:13 -0700137 void resetAnimationBackgroundAnimator() {
138 mAnimationBackgroundAnimator = null;
139 mAnimationBackgroundSurface.hide();
140 }
141
142 private long getDimBehindFadeDuration(long duration) {
143 TypedValue tv = new TypedValue();
144 mService.mContext.getResources().getValue(
145 com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
146 if (tv.type == TypedValue.TYPE_FRACTION) {
147 duration = (long)tv.getFraction(duration, duration);
148 } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
149 duration = tv.data;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800150 }
Craig Mautner05d29032013-05-03 13:40:13 -0700151 return duration;
152 }
153
154 boolean animateDimLayers() {
155 final int dimLayer;
156 final float dimAmount;
157 if (mDimWinAnimator == null) {
158 dimLayer = mDimLayer.getLayer();
159 dimAmount = 0;
160 } else {
161 dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
162 dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
163 }
164 final float targetAlpha = mDimLayer.getTargetAlpha();
165 if (targetAlpha != dimAmount) {
166 if (mDimWinAnimator == null) {
167 mDimLayer.hide(DEFAULT_DIM_DURATION);
168 } else {
169 long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
170 ? mDimWinAnimator.mAnimation.computeDurationHint()
171 : DEFAULT_DIM_DURATION;
172 if (targetAlpha > dimAmount) {
173 duration = getDimBehindFadeDuration(duration);
174 }
175 mDimLayer.show(dimLayer, dimAmount, duration);
176 }
177 } else if (mDimLayer.getLayer() != dimLayer) {
178 mDimLayer.setLayer(dimLayer);
179 }
180 if (mDimLayer.isAnimating()) {
181 if (!mService.okToDisplay()) {
182 // Jump to the end of the animation.
183 mDimLayer.show();
184 } else {
185 return mDimLayer.stepAnimation();
186 }
187 }
188 return false;
189 }
190
191 void resetDimmingTag() {
192 mDimmingTag = false;
193 }
194
195 void setDimmingTag() {
196 mDimmingTag = true;
197 }
198
199 boolean testDimmingTag() {
200 return mDimmingTag;
201 }
202
203 boolean isDimming() {
204 return mDimLayer.isDimming();
205 }
206
207 boolean isDimming(WindowStateAnimator winAnimator) {
208 return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
209 }
210
211 void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
212 // Only set dim params on the highest dimmed layer.
213 final WindowStateAnimator existingDimWinAnimator = mDimWinAnimator;
214 // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
215 if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
216 || !existingDimWinAnimator.mSurfaceShown
217 || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
218 mDimWinAnimator = newWinAnimator;
219 }
220 }
221
222 void stopDimmingIfNeeded() {
223 if (!mDimmingTag && isDimming()) {
224 mDimWinAnimator = null;
225 }
226 }
227
228 void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
229 int animLayer = winAnimator.mAnimLayer;
230 if (mAnimationBackgroundAnimator == null
231 || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
232 mAnimationBackgroundAnimator = winAnimator;
233 animLayer = mService.adjustAnimationBackground(winAnimator);
234 mAnimationBackgroundSurface.show(animLayer - WindowManagerService.LAYER_OFFSET_DIM,
235 ((color >> 24) & 0xff) / 255f, 0);
236 }
237 }
238
Craig Mautnerd76dcdc2013-06-06 11:26:15 -0700239 void setBounds(Rect bounds, boolean underStatusBar) {
Craig Mautner05d29032013-05-03 13:40:13 -0700240 mDimLayer.setBounds(bounds);
241 mAnimationBackgroundSurface.setBounds(bounds);
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700242
243 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
244 for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
245 final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
246 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
247 final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
248 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
249 final WindowState win = windows.get(winNdx);
250 if (!resizingWindows.contains(win)) {
251 resizingWindows.add(win);
252 }
Craig Mautnerd76dcdc2013-06-06 11:26:15 -0700253 win.mUnderStatusBar = underStatusBar;
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700254 }
255 }
256 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800257 }
Craig Mautner00af9fe2013-03-25 09:13:41 -0700258
259 public void dump(String prefix, PrintWriter pw) {
260 pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
261 for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
262 pw.print(prefix); pw.println(mTasks.get(taskNdx));
263 }
Craig Mautner05d29032013-05-03 13:40:13 -0700264 if (mAnimationBackgroundSurface.isDimming()) {
265 pw.print(prefix); pw.println("mWindowAnimationBackgroundSurface:");
266 mAnimationBackgroundSurface.printTo(prefix + " ", pw);
267 }
268 if (mDimLayer.isDimming()) {
269 pw.print(prefix); pw.println("mDimLayer:");
270 mDimLayer.printTo(prefix, pw);
271 pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
272 }
Craig Mautner00af9fe2013-03-25 09:13:41 -0700273 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700274
275 @Override
276 public String toString() {
277 return "{stackId=" + mStackId + " tasks=" + mTasks + "}";
278 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800279}