blob: 8b5f5acc5c28f0b59b23ec3f7bab98c59a89c419 [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
Jorim Jaggi2917dc42016-04-11 11:39:13 -070019import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
Chong Zhang73d4b442016-05-25 14:30:36 -070020import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070021import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
Jorim Jaggid3ec5072016-04-28 15:57:47 -070022import static android.app.ActivityManager.StackId.HOME_STACK_ID;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070023import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Wale Ogunwale51362492016-09-08 17:49:17 -070024import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070025import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
26import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Winson Chung303c6b72016-10-24 17:12:49 -070027import static android.view.Display.DEFAULT_DISPLAY;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070028import static android.view.WindowManager.DOCKED_BOTTOM;
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 Ogunwaleb0f3b832016-10-17 10:13:07 -070033import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Jorim Jaggiff71d202016-04-14 13:12:36 -070034import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -070035import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070036import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
37import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070038import static com.android.server.wm.WindowManagerService.LAYER_OFFSET_DIM;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070039
Wale Ogunwale3797c222015-10-27 14:21:58 -070040import android.app.ActivityManager.StackId;
Wale Ogunwale60454db2015-01-23 16:05:07 -080041import android.content.res.Configuration;
Craig Mautner05d29032013-05-03 13:40:13 -070042import android.graphics.Rect;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -070043import android.graphics.Region;
Filip Gruszczynski84fa3352016-01-25 16:28:49 -080044import android.os.RemoteException;
Craig Mautner2c2549c2013-11-12 08:31:15 -080045import android.util.EventLog;
Craig Mautnerf0ac5c82013-06-24 11:21:57 -070046import android.util.Slog;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070047import android.util.SparseArray;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070048import android.view.DisplayInfo;
Wale Ogunwale94744212015-09-21 19:01:47 -070049import android.view.Surface;
Filip Gruszczynski54977fe2015-10-19 17:26:45 -070050
Jorim Jaggi737af722015-12-31 10:42:27 +010051import com.android.internal.policy.DividerSnapAlgorithm;
52import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
53import com.android.internal.policy.DockedDividerUtils;
Craig Mautner2c2549c2013-11-12 08:31:15 -080054import com.android.server.EventLogTags;
Craig Mautner05d29032013-05-03 13:40:13 -070055
Craig Mautner00af9fe2013-03-25 09:13:41 -070056import java.io.PrintWriter;
Craig Mautnerc00204b2013-03-05 15:02:14 -080057
Wale Ogunwale14a3fb92016-09-11 15:19:05 -070058public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLayerUser,
Filip Gruszczynski84fa3352016-01-25 16:28:49 -080059 BoundsAnimationController.AnimateBoundsUser {
Chong Zhang198afac2016-04-15 12:03:11 -070060 /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
61 * restrict IME adjustment so that a min portion of top stack remains visible.*/
62 private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f;
63
64 /** Dimming amount for non-focused stack when stacks are IME-adjusted. */
65 private static final float IME_ADJUST_DIM_AMOUNT = 0.25f;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -070066
Craig Mautner00af9fe2013-03-25 09:13:41 -070067 /** Unique identifier */
Craig Mautnerc00204b2013-03-05 15:02:14 -080068 final int mStackId;
Craig Mautner00af9fe2013-03-25 09:13:41 -070069
Craig Mautner05d29032013-05-03 13:40:13 -070070 /** The service */
71 private final WindowManagerService mService;
72
Craig Mautner00af9fe2013-03-25 09:13:41 -070073 /** The display this stack sits under. */
Wale Ogunwale14a3fb92016-09-11 15:19:05 -070074 // TODO: Track parent marks like this in WindowContainer.
Craig Mautnerdf88d732014-01-27 09:21:32 -080075 private DisplayContent mDisplayContent;
Craig Mautner00af9fe2013-03-25 09:13:41 -070076
Craig Mautnerb660b9d2014-02-13 10:59:16 -080077 /** For comparison with DisplayContent bounds. */
78 private Rect mTmpRect = new Rect();
Wale Ogunwalee45899a2015-10-01 11:30:34 -070079 private Rect mTmpRect2 = new Rect();
Craig Mautnerb660b9d2014-02-13 10:59:16 -080080
81 /** Content limits relative to the DisplayContent this sits in. */
82 private Rect mBounds = new Rect();
83
Chong Zhangb816b862016-01-25 12:01:12 -080084 /** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
85 private final Rect mAdjustedBounds = new Rect();
86
Jorim Jaggieb88d832016-04-13 20:17:43 -070087 /**
88 * Fully adjusted IME bounds. These are different from {@link #mAdjustedBounds} because they
89 * represent the state when the animation has ended.
90 */
91 private final Rect mFullyAdjustedImeBounds = new Rect();
92
Craig Mautnerb660b9d2014-02-13 10:59:16 -080093 /** Whether mBounds is fullscreen */
Wale Ogunwale14a3fb92016-09-11 15:19:05 -070094 private boolean mFillsParent = true;
Craig Mautnerc00204b2013-03-05 15:02:14 -080095
Wale Ogunwale94744212015-09-21 19:01:47 -070096 // Device rotation as of the last time {@link #mBounds} was set.
Wale Ogunwale02319a62016-09-26 15:21:22 -070097 private int mRotation;
Wale Ogunwale94744212015-09-21 19:01:47 -070098
Jorim Jaggi11c62e12016-04-05 20:41:21 -070099 /** Density as of last time {@link #mBounds} was set. */
Wale Ogunwale02319a62016-09-26 15:21:22 -0700100 private int mDensity;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700101
Craig Mautner05d29032013-05-03 13:40:13 -0700102 /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
Wale Ogunwale02319a62016-09-26 15:21:22 -0700103 private DimLayer mAnimationBackgroundSurface;
Craig Mautner05d29032013-05-03 13:40:13 -0700104
105 /** The particular window with an Animation with non-zero background color. */
Wale Ogunwale02319a62016-09-26 15:21:22 -0700106 private WindowStateAnimator mAnimationBackgroundAnimator;
Craig Mautner05d29032013-05-03 13:40:13 -0700107
Craig Mautnerdc548482014-02-05 13:35:24 -0800108 /** Application tokens that are exiting, but still on screen for animations. */
109 final AppTokenList mExitingAppTokens = new AppTokenList();
110
Craig Mautner95da1082014-02-24 17:54:35 -0800111 /** Detach this stack from its display when animation completes. */
Wale Ogunwalef6192862016-09-10 13:42:30 -0700112 // TODO: maybe tie this to WindowContainer#removeChild some how...
Wale Ogunwale10124582016-09-15 20:25:50 -0700113 boolean mDeferRemoval;
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800114
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800115 private final Rect mTmpAdjustedBounds = new Rect();
116 private boolean mAdjustedForIme;
Chong Zhangbaba7832016-03-24 10:21:26 -0700117 private boolean mImeGoingAway;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800118 private WindowState mImeWin;
119 private float mMinimizeAmount;
Jorim Jaggieb88d832016-04-13 20:17:43 -0700120 private float mAdjustImeAmount;
Chong Zhangf347ab52016-04-18 21:02:01 -0700121 private float mAdjustDividerAmount;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800122 private final int mDockedStackMinimizeThickness;
123
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700124 // If this is true, we are in the bounds animating mode. The task will be down or upscaled to
125 // perfectly fit the region it would have been cropped to. We may also avoid certain logic we
126 // would otherwise apply while resizing, while resizing in the bounds animating mode.
Robert Carr1ca6a332016-04-11 18:00:43 -0700127 private boolean mBoundsAnimating = false;
Robert Carr7e4c90e2017-02-15 19:52:38 -0800128 private boolean mBoundsAnimatingToFullscreen = false;
Winson Chung84a38342016-11-08 16:15:10 -0800129 private Rect mBoundsAnimationTarget = new Rect();
Winson Chung08f81892017-03-02 15:40:51 -0800130 private Rect mBoundsAnimationSourceBounds = new Rect();
Robert Carr0d00c2e2016-02-29 17:45:02 -0800131
Chong Zhang167bbfac2016-03-31 09:44:34 -0700132 // Temporary storage for the new bounds that should be used after the configuration change.
133 // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
134 private final Rect mBoundsAfterRotation = new Rect();
135
Craig Mautnerdf88d732014-01-27 09:21:32 -0800136 TaskStack(WindowManagerService service, int stackId) {
Craig Mautner05d29032013-05-03 13:40:13 -0700137 mService = service;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800138 mStackId = stackId;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800139 mDockedStackMinimizeThickness = service.mContext.getResources().getDimensionPixelSize(
140 com.android.internal.R.dimen.docked_stack_minimize_thickness);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700141 EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800142 }
143
144 DisplayContent getDisplayContent() {
145 return mDisplayContent;
146 }
147
Jorim Jaggid3ec5072016-04-28 15:57:47 -0700148 Task findHomeTask() {
149 if (mStackId != HOME_STACK_ID) {
150 return null;
151 }
152
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700153 for (int i = mChildren.size() - 1; i >= 0; i--) {
154 if (mChildren.get(i).isHomeTask()) {
155 return mChildren.get(i);
Jorim Jaggid3ec5072016-04-28 15:57:47 -0700156 }
157 }
158 return null;
159 }
160
Wale Ogunwale15ead902016-09-02 14:30:11 -0700161 boolean hasMultipleTaskWithHomeTaskNotTop() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700162 return mChildren.size() > 1 && !mChildren.get(mChildren.size() - 1).isHomeTask();
Wale Ogunwale15ead902016-09-02 14:30:11 -0700163 }
164
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700165 /**
166 * Set the bounds of the stack and its containing tasks.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700167 * @param stackBounds New stack bounds. Passing in null sets the bounds to fullscreen.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700168 * @param configs Configuration for individual tasks, keyed by task id.
169 * @param taskBounds Bounds for individual tasks, keyed by task id.
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700170 * @return True if the stack bounds was changed.
171 * */
Wale Ogunwalea6e902e2015-09-21 18:37:15 -0700172 boolean setBounds(
Jorim Jaggidc249c42015-12-15 14:57:31 -0800173 Rect stackBounds, SparseArray<Configuration> configs, SparseArray<Rect> taskBounds,
174 SparseArray<Rect> taskTempInsetBounds) {
Jorim Jaggi899327f2016-02-25 20:44:18 -0500175 setBounds(stackBounds);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700176
177 // Update bounds of containing tasks.
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700178 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
179 final Task task = mChildren.get(taskNdx);
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700180 Configuration config = configs.get(task.mTaskId);
181 if (config != null) {
182 Rect bounds = taskBounds.get(task.mTaskId);
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700183 task.resizeLocked(bounds, config, false /* forced */);
184 task.setTempInsetBounds(taskTempInsetBounds != null ?
185 taskTempInsetBounds.get(task.mTaskId) : null);
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700186 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800187 Slog.wtf(TAG_WM, "No config for task: " + task + ", is there a mismatch with AM?");
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700188 }
189 }
190 return true;
191 }
192
Jorim Jaggi0429f352015-12-22 16:29:16 +0100193 void prepareFreezingTaskBounds() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700194 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
195 final Task task = mChildren.get(taskNdx);
Jorim Jaggi0429f352015-12-22 16:29:16 +0100196 task.prepareFreezingBounds();
197 }
198 }
199
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800200 /**
201 * Overrides the adjusted bounds, i.e. sets temporary layout bounds which are different from
202 * the normal task bounds.
203 *
204 * @param bounds The adjusted bounds.
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800205 */
Jorim Jaggieb88d832016-04-13 20:17:43 -0700206 private void setAdjustedBounds(Rect bounds) {
207 if (mAdjustedBounds.equals(bounds) && !isAnimatingForIme()) {
208 return;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800209 }
210
211 mAdjustedBounds.set(bounds);
212 final boolean adjusted = !mAdjustedBounds.isEmpty();
Jorim Jaggieb88d832016-04-13 20:17:43 -0700213 Rect insetBounds = null;
Matthew Nge15352e2016-12-20 15:36:29 -0800214 if (adjusted && isAdjustedForMinimizedDockedStack()) {
Jorim Jaggieb88d832016-04-13 20:17:43 -0700215 insetBounds = mBounds;
Chong Zhang5117e272016-05-03 12:47:34 -0700216 } else if (adjusted && mAdjustedForIme) {
Jorim Jaggieb88d832016-04-13 20:17:43 -0700217 if (mImeGoingAway) {
218 insetBounds = mBounds;
219 } else {
220 insetBounds = mFullyAdjustedImeBounds;
221 }
222 }
Chong Zhang741c0ba2016-05-27 12:52:11 -0700223 alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : mBounds, insetBounds);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700224 mDisplayContent.setLayoutNeeded();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800225 }
226
227 private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700228 if (mFillsParent) {
Chong Zhangb816b862016-01-25 12:01:12 -0800229 return;
230 }
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700231
232 final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
233
Chong Zhangb816b862016-01-25 12:01:12 -0800234 // Update bounds of containing tasks.
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700235 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
236 final Task task = mChildren.get(taskNdx);
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700237 task.alignToAdjustedBounds(adjustedBounds, tempInsetBounds, alignBottom);
Chong Zhangb816b862016-01-25 12:01:12 -0800238 }
239 }
240
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700241 private boolean setBounds(Rect bounds) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700242 boolean oldFullscreen = mFillsParent;
Wale Ogunwale94744212015-09-21 19:01:47 -0700243 int rotation = Surface.ROTATION_0;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700244 int density = DENSITY_DPI_UNDEFINED;
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800245 if (mDisplayContent != null) {
246 mDisplayContent.getLogicalDisplayRect(mTmpRect);
Wale Ogunwale94744212015-09-21 19:01:47 -0700247 rotation = mDisplayContent.getDisplayInfo().rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700248 density = mDisplayContent.getDisplayInfo().logicalDensityDpi;
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700249 mFillsParent = bounds == null;
250 if (mFillsParent) {
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800251 bounds = mTmpRect;
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800252 }
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800253 }
254
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800255 if (bounds == null) {
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800256 // Can't set to fullscreen if we don't have a display to get bounds from...
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800257 return false;
258 }
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700259 if (mBounds.equals(bounds) && oldFullscreen == mFillsParent && mRotation == rotation) {
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800260 return false;
261 }
262
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700263 if (mDisplayContent != null) {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800264 mDisplayContent.mDimLayerController.updateDimLayer(this);
Winson Chung47f2bf62017-02-16 18:58:12 -0800265 if (mStackId == PINNED_STACK_ID) {
266 // Update the bounds based on any changes to the display info
267 getAnimatingBounds(mTmpRect2);
268 mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(mTmpRect2,
269 bounds);
270 }
Filip Gruszczynski57b6cce2015-10-06 09:50:51 -0700271 mAnimationBackgroundSurface.setBounds(bounds);
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700272 }
273
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800274 mBounds.set(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -0700275 mRotation = rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700276 mDensity = density;
Chong Zhangb816b862016-01-25 12:01:12 -0800277
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800278 updateAdjustedBounds();
Chong Zhangb816b862016-01-25 12:01:12 -0800279
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800280 return true;
281 }
282
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700283 /** Bounds of the stack without adjusting for other factors in the system like visibility
284 * of docked stack.
285 * Most callers should be using {@link #getBounds} as it take into consideration other system
286 * factors. */
287 void getRawBounds(Rect out) {
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800288 out.set(mBounds);
289 }
290
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700291 /** Return true if the current bound can get outputted to the rest of the system as-is. */
292 private boolean useCurrentBounds() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700293 if (mFillsParent
Wale Ogunwale3797c222015-10-27 14:21:58 -0700294 || !StackId.isResizeableByDockedStack(mStackId)
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700295 || mDisplayContent == null
296 || mDisplayContent.getDockedStackLocked() != null) {
297 return true;
298 }
299 return false;
300 }
301
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700302 public void getBounds(Rect out) {
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700303 if (useCurrentBounds()) {
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800304 // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
305 // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
306 // stack is visible since it is already what we want to represent to the rest of the
307 // system.
308 if (!mAdjustedBounds.isEmpty()) {
Chong Zhangb816b862016-01-25 12:01:12 -0800309 out.set(mAdjustedBounds);
310 } else {
311 out.set(mBounds);
312 }
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700313 return;
314 }
315
316 // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
317 // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
318 // system.
319 mDisplayContent.getLogicalDisplayRect(out);
320 }
321
Winson Chung84a38342016-11-08 16:15:10 -0800322 /**
323 * Sets the bounds animation target bounds. This can't currently be done in onAnimationStart()
324 * since that is started on the UiThread.
325 */
Winson Chung08f81892017-03-02 15:40:51 -0800326 void setAnimatingBounds(Rect sourceBounds, Rect destBounds) {
327 if (sourceBounds != null) {
328 mBoundsAnimationSourceBounds.set(sourceBounds);
329 } else {
330 mBoundsAnimationSourceBounds.setEmpty();
331 }
332 if (destBounds != null) {
333 mBoundsAnimationTarget.set(destBounds);
Winson Chung84a38342016-11-08 16:15:10 -0800334 } else {
335 mBoundsAnimationTarget.setEmpty();
336 }
337 }
338
339 /**
Winson Chung08f81892017-03-02 15:40:51 -0800340 * @return the source bounds for the bounds animation.
341 */
342 void getAnimatingSourceBounds(Rect outBounds) {
Winson Chunga2249ac2017-03-30 18:15:30 -0700343 if (!mBoundsAnimationSourceBounds.isEmpty()) {
Winson Chung08f81892017-03-02 15:40:51 -0800344 outBounds.set(mBoundsAnimationSourceBounds);
345 return;
346 }
347 outBounds.setEmpty();
348 }
349
350 /**
Winson Chung84a38342016-11-08 16:15:10 -0800351 * @return the bounds that the task stack is currently being animated towards, or the current
352 * stack bounds if there is no animation in progress.
353 */
354 void getAnimatingBounds(Rect outBounds) {
355 if (!mBoundsAnimationTarget.isEmpty()) {
356 outBounds.set(mBoundsAnimationTarget);
357 return;
358 }
359 getBounds(outBounds);
360 }
361
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800362 /** Bounds of the stack with other system factors taken into consideration. */
363 @Override
364 public void getDimBounds(Rect out) {
365 getBounds(out);
366 }
367
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700368 void updateDisplayInfo(Rect bounds) {
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800369 if (mDisplayContent == null) {
370 return;
371 }
Jorim Jaggi737af722015-12-31 10:42:27 +0100372
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700373 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
374 mChildren.get(taskNdx).updateDisplayInfo(mDisplayContent);
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800375 }
376 if (bounds != null) {
377 setBounds(bounds);
378 return;
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700379 } else if (mFillsParent) {
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800380 setBounds(null);
381 return;
382 }
383
384 mTmpRect2.set(mBounds);
385 final int newRotation = mDisplayContent.getDisplayInfo().rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700386 final int newDensity = mDisplayContent.getDisplayInfo().logicalDensityDpi;
387 if (mRotation == newRotation && mDensity == newDensity) {
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800388 setBounds(mTmpRect2);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800389 }
Jorim Jaggieb1cb922016-04-27 20:37:45 -0700390
391 // If the rotation or density didn't match, we'll update it in onConfigurationChanged.
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800392 }
393
Andrii Kulian441e4492016-09-29 15:25:00 -0700394 /** @return true if bounds were updated to some non-empty value. */
395 boolean updateBoundsAfterConfigChange() {
Andrii Kulian0be2cfe2016-05-25 14:27:39 -0700396 if (mDisplayContent == null) {
397 // If the stack is already detached we're not updating anything,
398 // as it's going away soon anyway.
399 return false;
400 }
Jorim Jaggi737af722015-12-31 10:42:27 +0100401 final int newRotation = getDisplayInfo().rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700402 final int newDensity = getDisplayInfo().logicalDensityDpi;
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800403
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700404 if (mRotation == newRotation && mDensity == newDensity) {
Jorim Jaggieb1cb922016-04-27 20:37:45 -0700405 // Nothing to do here as we already update the state in updateDisplayInfo.
Chong Zhang167bbfac2016-03-31 09:44:34 -0700406 return false;
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800407 }
408
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700409 if (mFillsParent) {
Chong Zhangccc335c2016-05-13 11:04:38 -0700410 // Update stack bounds again since rotation changed since updateDisplayInfo().
411 setBounds(null);
412 // Return false since we don't need the client to resize.
413 return false;
414 }
415
Winson Chung47f2bf62017-02-16 18:58:12 -0800416 if (StackId.tasksAreFloating(mStackId)) {
417 // Update stack bounds again since the display info has changed since updateDisplayInfo,
418 // however, for floating tasks, we don't need to apply the new rotation to the bounds,
419 // we can just update and return them here
420 setBounds(mBounds);
421 mBoundsAfterRotation.set(mBounds);
Winson Chunga2249ac2017-03-30 18:15:30 -0700422
423 // Once we've set the bounds based on the rotation of the old bounds in the new
424 // orientation, clear the animation target bounds since they are obsolete
425 mBoundsAnimationTarget.setEmpty();
426 mBoundsAnimationSourceBounds.setEmpty();
Winson Chung47f2bf62017-02-16 18:58:12 -0800427 return true;
428 }
429
Wale Ogunwale5952f9a2016-04-25 13:40:30 -0700430 mTmpRect2.set(mBounds);
Jorim Jaggi737af722015-12-31 10:42:27 +0100431 mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
Winson Chungcd1ff642016-10-26 09:44:43 -0700432 switch (mStackId) {
Winson Chungcd1ff642016-10-26 09:44:43 -0700433 case DOCKED_STACK_ID:
434 repositionDockedStackAfterRotation(mTmpRect2);
435 snapDockedStackAfterRotation(mTmpRect2);
436 final int newDockSide = getDockSide(mTmpRect2);
437
438 // Update the dock create mode and clear the dock create bounds, these
439 // might change after a rotation and the original values will be invalid.
440 mService.setDockedStackCreateStateLocked(
441 (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
442 ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
443 : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
444 null);
445 mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
446 break;
Jorim Jaggi737af722015-12-31 10:42:27 +0100447 }
448
Jorim Jaggieb1cb922016-04-27 20:37:45 -0700449 mBoundsAfterRotation.set(mTmpRect2);
Chong Zhang167bbfac2016-03-31 09:44:34 -0700450 return true;
451 }
452
Matthew Ngaa2b6202017-02-10 14:48:21 -0800453 void getBoundsForNewConfiguration(Rect outBounds) {
Chong Zhang167bbfac2016-03-31 09:44:34 -0700454 outBounds.set(mBoundsAfterRotation);
455 mBoundsAfterRotation.setEmpty();
Jorim Jaggi737af722015-12-31 10:42:27 +0100456 }
457
458 /**
Jorim Jaggi5060bd82016-02-19 17:12:19 -0800459 * Some dock sides are not allowed by the policy. This method queries the policy and moves
460 * the docked stack around if needed.
461 *
462 * @param inOutBounds the bounds of the docked stack to adjust
463 */
464 private void repositionDockedStackAfterRotation(Rect inOutBounds) {
465 int dockSide = getDockSide(inOutBounds);
466 if (mService.mPolicy.isDockSideAllowed(dockSide)) {
467 return;
468 }
469 mDisplayContent.getLogicalDisplayRect(mTmpRect);
470 dockSide = DockedDividerUtils.invertDockSide(dockSide);
471 switch (dockSide) {
472 case DOCKED_LEFT:
473 int movement = inOutBounds.left;
474 inOutBounds.left -= movement;
475 inOutBounds.right -= movement;
476 break;
477 case DOCKED_RIGHT:
478 movement = mTmpRect.right - inOutBounds.right;
479 inOutBounds.left += movement;
480 inOutBounds.right += movement;
481 break;
482 case DOCKED_TOP:
483 movement = inOutBounds.top;
484 inOutBounds.top -= movement;
485 inOutBounds.bottom -= movement;
486 break;
487 case DOCKED_BOTTOM:
488 movement = mTmpRect.bottom - inOutBounds.bottom;
489 inOutBounds.top += movement;
490 inOutBounds.bottom += movement;
491 break;
492 }
493 }
494
495 /**
Jorim Jaggi737af722015-12-31 10:42:27 +0100496 * Snaps the bounds after rotation to the closest snap target for the docked stack.
497 */
498 private void snapDockedStackAfterRotation(Rect outBounds) {
499
500 // Calculate the current position.
501 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700502 final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
Jorim Jaggi737af722015-12-31 10:42:27 +0100503 final int dockSide = getDockSide(outBounds);
504 final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
505 dockSide, dividerSize);
506 final int displayWidth = mDisplayContent.getDisplayInfo().logicalWidth;
507 final int displayHeight = mDisplayContent.getDisplayInfo().logicalHeight;
508
509 // Snap the position to a target.
510 final int rotation = displayInfo.rotation;
Andrii Kulian441e4492016-09-29 15:25:00 -0700511 final int orientation = mDisplayContent.getConfiguration().orientation;
Jorim Jaggi737af722015-12-31 10:42:27 +0100512 mService.mPolicy.getStableInsetsLw(rotation, displayWidth, displayHeight, outBounds);
513 final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
Jorim Jaggidf012d52016-01-15 22:40:13 -0800514 mService.mContext.getResources(), displayWidth, displayHeight,
Matthew Nge15352e2016-12-20 15:36:29 -0800515 dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
516 isMinimizedDockAndHomeStackResizable());
Jorim Jaggi737af722015-12-31 10:42:27 +0100517 final SnapTarget target = algorithm.calculateNonDismissingSnapTarget(dividerPosition);
518
519 // Recalculate the bounds based on the position of the target.
520 DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
521 outBounds, displayInfo.logicalWidth, displayInfo.logicalHeight,
522 dividerSize);
523 }
524
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700525 // TODO: Checkout the call points of this method and the ones below to see how they can fit in WC.
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800526 void addTask(Task task, int position) {
527 addTask(task, position, task.showForAllUsers(), true /* moveParents */);
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700528 }
529
Craig Mautner00af9fe2013-03-25 09:13:41 -0700530 /**
Andrii Kuliand2765632016-12-12 22:26:34 -0800531 * Put a Task in this stack. Used for adding only.
532 * When task is added to top of the stack, the entire branch of the hierarchy (including stack
533 * and display) will be brought to top.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700534 * @param task The task to add.
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800535 * @param position Target position to add the task to.
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700536 * @param showForAllUsers Whether to show the task regardless of the current user.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700537 */
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800538 void addTask(Task task, int position, boolean showForAllUsers, boolean moveParents) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800539 final TaskStack currentStack = task.mStack;
540 // TODO: We pass stack to task's constructor, but we still need to call this method.
541 // This doesn't make sense, mStack will already be set equal to "this" at this point.
542 if (currentStack != null && currentStack.mStackId != mStackId) {
543 throw new IllegalStateException("Trying to add taskId=" + task.mTaskId
544 + " to stackId=" + mStackId
545 + ", but it is already attached to stackId=" + task.mStack.mStackId);
546 }
547
Andrii Kuliand2765632016-12-12 22:26:34 -0800548 // Add child task.
549 task.mStack = this;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800550 addChild(task, null);
Andrii Kuliand2765632016-12-12 22:26:34 -0800551
552 // Move child to a proper position, as some restriction for position might apply.
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800553 positionChildAt(position, task, moveParents /* includingParents */, showForAllUsers);
Andrii Kuliand2765632016-12-12 22:26:34 -0800554 }
555
556 @Override
557 void positionChildAt(int position, Task child, boolean includingParents) {
558 positionChildAt(position, child, includingParents, child.showForAllUsers());
559 }
560
561 /**
562 * Overridden version of {@link TaskStack#positionChildAt(int, Task, boolean)}. Used in
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800563 * {@link TaskStack#addTask(Task, int, boolean showForAllUsers, boolean)}, as it can receive
Andrii Kuliand2765632016-12-12 22:26:34 -0800564 * showForAllUsers param from {@link AppWindowToken} instead of {@link Task#showForAllUsers()}.
565 */
566 private void positionChildAt(int position, Task child, boolean includingParents,
567 boolean showForAllUsers) {
568 final int targetPosition = findPositionForTask(child, position, showForAllUsers,
569 false /* addingNew */);
570 super.positionChildAt(targetPosition, child, includingParents);
571
572 // Log positioning.
573 if (DEBUG_TASK_MOVEMENT)
574 Slog.d(TAG_WM, "positionTask: task=" + this + " position=" + position);
575
576 final int toTop = targetPosition == mChildren.size() - 1 ? 1 : 0;
577 EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, child.mTaskId, toTop, targetPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700578 }
579
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700580 // TODO: We should really have users as a window container in the hierarchy so that we don't
Andrii Kuliand2765632016-12-12 22:26:34 -0800581 // have to do complicated things like we are doing in this method.
582 private int findPositionForTask(Task task, int targetPosition, boolean showForAllUsers,
583 boolean addingNew) {
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700584 final boolean canShowTask =
585 showForAllUsers || mService.isCurrentProfileLocked(task.mUserId);
Andrii Kuliand2765632016-12-12 22:26:34 -0800586
587 final int stackSize = mChildren.size();
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700588 int minPosition = 0;
Andrii Kuliand2765632016-12-12 22:26:34 -0800589 int maxPosition = addingNew ? stackSize : stackSize - 1;
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700590
591 if (canShowTask) {
592 minPosition = computeMinPosition(minPosition, stackSize);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700593 } else {
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700594 maxPosition = computeMaxPosition(maxPosition);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700595 }
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700596 // Reset position based on minimum/maximum possible positions.
Andrii Kuliand2765632016-12-12 22:26:34 -0800597 return Math.min(Math.max(targetPosition, minPosition), maxPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700598 }
599
600 /** Calculate the minimum possible position for a task that can be shown to the user.
601 * The minimum position will be above all other tasks that can't be shown.
602 * @param minPosition The minimum position the caller is suggesting.
603 * We will start adjusting up from here.
604 * @param size The size of the current task list.
605 */
606 private int computeMinPosition(int minPosition, int size) {
607 while (minPosition < size) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700608 final Task tmpTask = mChildren.get(minPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700609 final boolean canShowTmpTask =
610 tmpTask.showForAllUsers()
611 || mService.isCurrentProfileLocked(tmpTask.mUserId);
612 if (canShowTmpTask) {
613 break;
614 }
615 minPosition++;
616 }
617 return minPosition;
618 }
619
620 /** Calculate the maximum possible position for a task that can't be shown to the user.
621 * The maximum position will be below all other tasks that can be shown.
622 * @param maxPosition The maximum position the caller is suggesting.
623 * We will start adjusting down from here.
624 */
625 private int computeMaxPosition(int maxPosition) {
626 while (maxPosition > 0) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800627 final Task tmpTask = mChildren.get(maxPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700628 final boolean canShowTmpTask =
629 tmpTask.showForAllUsers()
630 || mService.isCurrentProfileLocked(tmpTask.mUserId);
631 if (!canShowTmpTask) {
632 break;
633 }
634 maxPosition--;
635 }
636 return maxPosition;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800637 }
638
Craig Mautner00af9fe2013-03-25 09:13:41 -0700639 /**
Craig Mautner04a0ea62014-01-13 12:51:26 -0800640 * Delete a Task from this stack. If it is the last Task in the stack, move this stack to the
641 * back.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700642 * @param task The Task to delete.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700643 */
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700644 @Override
645 void removeChild(Task task) {
646 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "removeChild: task=" + task);
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700647
648 super.removeChild(task);
Andrii Kuliand2765632016-12-12 22:26:34 -0800649 task.mStack = null;
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700650
Craig Mautnerdf88d732014-01-27 09:21:32 -0800651 if (mDisplayContent != null) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700652 if (mChildren.isEmpty()) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800653 getParent().positionChildAt(POSITION_BOTTOM, this, false /* includingParents */);
Craig Mautnerdf88d732014-01-27 09:21:32 -0800654 }
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700655 mDisplayContent.setLayoutNeeded();
Craig Mautner04a0ea62014-01-13 12:51:26 -0800656 }
Craig Mautnere3119b72015-01-20 15:02:36 -0800657 for (int appNdx = mExitingAppTokens.size() - 1; appNdx >= 0; --appNdx) {
658 final AppWindowToken wtoken = mExitingAppTokens.get(appNdx);
Bryce Lee6d410262017-02-28 15:30:17 -0800659 if (wtoken.getTask() == task) {
Craig Mautnere3119b72015-01-20 15:02:36 -0800660 wtoken.mIsExiting = false;
661 mExitingAppTokens.remove(appNdx);
662 }
663 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800664 }
665
Wale Ogunwale02319a62016-09-26 15:21:22 -0700666 void onDisplayChanged(DisplayContent dc) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800667 if (mDisplayContent != null) {
Wale Ogunwale02319a62016-09-26 15:21:22 -0700668 throw new IllegalStateException("onDisplayChanged: Already attached");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800669 }
Craig Mautnerdf88d732014-01-27 09:21:32 -0800670
Wale Ogunwale02319a62016-09-26 15:21:22 -0700671 mDisplayContent = dc;
Jorim Jaggibc5425c2016-03-01 13:51:16 +0100672 mAnimationBackgroundSurface = new DimLayer(mService, this, mDisplayContent.getDisplayId(),
673 "animation background stackId=" + mStackId);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700674
675 Rect bounds = null;
Wale Ogunwale1666e312016-12-16 11:27:18 -0800676 final TaskStack dockedStack = dc.getDockedStackIgnoringVisibility();
Wale Ogunwale3797c222015-10-27 14:21:58 -0700677 if (mStackId == DOCKED_STACK_ID
Jorim Jaggi65002e12016-04-21 18:25:49 -0700678 || (dockedStack != null && StackId.isResizeableByDockedStack(mStackId)
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700679 && !dockedStack.fillsParent())) {
Wale Ogunwale3797c222015-10-27 14:21:58 -0700680 // The existence of a docked stack affects the size of other static stack created since
Jorim Jaggi65002e12016-04-21 18:25:49 -0700681 // the docked stack occupies a dedicated region on screen, but only if the dock stack is
682 // not fullscreen. If it's fullscreen, it means that we are in the transition of
683 // dismissing it, so we must not resize this stack.
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700684 bounds = new Rect();
Wale Ogunwale02319a62016-09-26 15:21:22 -0700685 dc.getLogicalDisplayRect(mTmpRect);
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700686 mTmpRect2.setEmpty();
687 if (dockedStack != null) {
688 dockedStack.getRawBounds(mTmpRect2);
689 }
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -0800690 final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700691 == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
692 getStackDockedModeBounds(mTmpRect, bounds, mStackId, mTmpRect2,
Jorim Jaggi1fcbab62015-11-04 16:39:50 +0100693 mDisplayContent.mDividerControllerLocked.getContentWidth(),
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700694 dockedOnTopOrLeft);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700695 }
696
697 updateDisplayInfo(bounds);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700698 super.onDisplayChanged(dc);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700699 }
700
Matthew Ngaa2b6202017-02-10 14:48:21 -0800701 /**
702 * Determines the stack and task bounds of the other stack when in docked mode. The current task
703 * bounds is passed in but depending on the stack, the task and stack must match. Only in
704 * minimized mode with resizable launcher, the other stack ignores calculating the stack bounds
705 * and uses the task bounds passed in as the stack and task bounds, otherwise the stack bounds
706 * is calculated and is also used for its task bounds.
707 * If any of the out bounds are empty, it represents default bounds
708 *
709 * @param currentTempTaskBounds the current task bounds of the other stack
710 * @param outStackBounds the calculated stack bounds of the other stack
711 * @param outTempTaskBounds the calculated task bounds of the other stack
712 * @param ignoreVisibility ignore visibility in getting the stack bounds
713 */
714 void getStackDockedModeBoundsLocked(Rect currentTempTaskBounds, Rect outStackBounds,
715 Rect outTempTaskBounds, boolean ignoreVisibility) {
716 outTempTaskBounds.setEmpty();
717
718 // When the home stack is resizable, should always have the same stack and task bounds
Matthew Nge15352e2016-12-20 15:36:29 -0800719 if (mStackId == HOME_STACK_ID && findHomeTask().isResizeable()) {
720 // Calculate the home stack bounds when in docked mode
721 getDisplayContent().mDividerControllerLocked
Matthew Ngaa2b6202017-02-10 14:48:21 -0800722 .getHomeStackBoundsInDockedMode(outStackBounds);
723 outTempTaskBounds.set(outStackBounds);
724 return;
725 }
726
727 // When minimized state, the stack bounds for all non-home and docked stack bounds should
728 // match the passed task bounds
729 if (isMinimizedDockAndHomeStackResizable() && currentTempTaskBounds != null) {
730 outStackBounds.set(currentTempTaskBounds);
731 return;
Matthew Nge15352e2016-12-20 15:36:29 -0800732 }
733
Wale Ogunwalea9f9b372016-02-04 18:04:39 -0800734 if ((mStackId != DOCKED_STACK_ID && !StackId.isResizeableByDockedStack(mStackId))
735 || mDisplayContent == null) {
Matthew Ngaa2b6202017-02-10 14:48:21 -0800736 outStackBounds.set(mBounds);
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700737 return;
738 }
739
Wale Ogunwale1666e312016-12-16 11:27:18 -0800740 final TaskStack dockedStack = mDisplayContent.getDockedStackIgnoringVisibility();
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700741 if (dockedStack == null) {
742 // Not sure why you are calling this method when there is no docked stack...
743 throw new IllegalStateException(
744 "Calling getStackDockedModeBoundsLocked() when there is no docked stack.");
745 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700746 if (!ignoreVisibility && !dockedStack.isVisible()) {
Filip Gruszczynski54977fe2015-10-19 17:26:45 -0700747 // The docked stack is being dismissed, but we caught before it finished being
748 // dismissed. In that case we want to treat it as if it is not occupying any space and
749 // let others occupy the whole display.
Matthew Ngaa2b6202017-02-10 14:48:21 -0800750 mDisplayContent.getLogicalDisplayRect(outStackBounds);
Filip Gruszczynski54977fe2015-10-19 17:26:45 -0700751 return;
752 }
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700753
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700754 final int dockedSide = dockedStack.getDockSide();
755 if (dockedSide == DOCKED_INVALID) {
756 // Not sure how you got here...Only thing we can do is return current bounds.
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800757 Slog.e(TAG_WM, "Failed to get valid docked side for docked stack=" + dockedStack);
Matthew Ngaa2b6202017-02-10 14:48:21 -0800758 outStackBounds.set(mBounds);
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700759 return;
760 }
761
762 mDisplayContent.getLogicalDisplayRect(mTmpRect);
763 dockedStack.getRawBounds(mTmpRect2);
Wale Ogunwalea9f9b372016-02-04 18:04:39 -0800764 final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
Matthew Ngaa2b6202017-02-10 14:48:21 -0800765 getStackDockedModeBounds(mTmpRect, outStackBounds, mStackId, mTmpRect2,
Jorim Jaggi1fcbab62015-11-04 16:39:50 +0100766 mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700767
768 }
769
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700770 /**
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700771 * Outputs the bounds a stack should be given the presence of a docked stack on the display.
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700772 * @param displayRect The bounds of the display the docked stack is on.
773 * @param outBounds Output bounds that should be used for the stack.
774 * @param stackId Id of stack we are calculating the bounds for.
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700775 * @param dockedBounds Bounds of the docked stack.
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700776 * @param dockDividerWidth We need to know the width of the divider make to the output bounds
777 * close to the side of the dock.
778 * @param dockOnTopOrLeft If the docked stack is on the top or left side of the screen.
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700779 */
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -0800780 private void getStackDockedModeBounds(
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700781 Rect displayRect, Rect outBounds, int stackId, Rect dockedBounds, int dockDividerWidth,
782 boolean dockOnTopOrLeft) {
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700783 final boolean dockedStack = stackId == DOCKED_STACK_ID;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700784 final boolean splitHorizontally = displayRect.width() > displayRect.height();
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700785
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700786 outBounds.set(displayRect);
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700787 if (dockedStack) {
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -0800788 if (mService.mDockedStackCreateBounds != null) {
789 outBounds.set(mService.mDockedStackCreateBounds);
790 return;
791 }
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100792
793 // The initial bounds of the docked stack when it is created about half the screen space
794 // and its bounds can be adjusted after that. The bounds of all other stacks are
795 // adjusted to occupy whatever screen space the docked stack isn't occupying.
796 final DisplayInfo di = mDisplayContent.getDisplayInfo();
797 mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
798 mTmpRect2);
799 final int position = new DividerSnapAlgorithm(mService.mContext.getResources(),
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100800 di.logicalWidth,
801 di.logicalHeight,
802 dockDividerWidth,
Andrii Kulian441e4492016-09-29 15:25:00 -0700803 mDisplayContent.getConfiguration().orientation == ORIENTATION_PORTRAIT,
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100804 mTmpRect2).getMiddleTarget().position;
805
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700806 if (dockOnTopOrLeft) {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700807 if (splitHorizontally) {
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100808 outBounds.right = position;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700809 } else {
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100810 outBounds.bottom = position;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700811 }
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700812 } else {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700813 if (splitHorizontally) {
Andrii Kulianef3b2722016-04-08 12:45:27 -0700814 outBounds.left = position + dockDividerWidth;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700815 } else {
Andrii Kulianef3b2722016-04-08 12:45:27 -0700816 outBounds.top = position + dockDividerWidth;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700817 }
818 }
819 return;
820 }
821
822 // Other stacks occupy whatever space is left by the docked stack.
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700823 if (!dockOnTopOrLeft) {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700824 if (splitHorizontally) {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700825 outBounds.right = dockedBounds.left - dockDividerWidth;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700826 } else {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700827 outBounds.bottom = dockedBounds.top - dockDividerWidth;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700828 }
829 } else {
830 if (splitHorizontally) {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700831 outBounds.left = dockedBounds.right + dockDividerWidth;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700832 } else {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700833 outBounds.top = dockedBounds.bottom + dockDividerWidth;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700834 }
835 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800836 DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700837 }
838
Wale Ogunwalea9f9b372016-02-04 18:04:39 -0800839 void resetDockedStackToMiddle() {
840 if (mStackId != DOCKED_STACK_ID) {
841 throw new IllegalStateException("Not a docked stack=" + this);
842 }
843
844 mService.mDockedStackCreateBounds = null;
845
846 final Rect bounds = new Rect();
Matthew Nge15352e2016-12-20 15:36:29 -0800847 final Rect tempBounds = new Rect();
Matthew Ngaa2b6202017-02-10 14:48:21 -0800848 getStackDockedModeBoundsLocked(null /* currentTempTaskBounds */, bounds, tempBounds,
849 true /*ignoreVisibility*/);
Wale Ogunwale1666e312016-12-16 11:27:18 -0800850 getController().requestResize(bounds);
851 }
852
853 @Override
854 StackWindowController getController() {
855 return (StackWindowController) super.getController();
Wale Ogunwalea9f9b372016-02-04 18:04:39 -0800856 }
857
Wale Ogunwale10124582016-09-15 20:25:50 -0700858 @Override
859 void removeIfPossible() {
860 if (isAnimating()) {
861 mDeferRemoval = true;
862 return;
863 }
864 removeImmediately();
865 }
866
867 @Override
868 void removeImmediately() {
869 super.removeImmediately();
870
Andrii Kulian839def92016-11-02 10:58:58 -0700871 onRemovedFromDisplay();
872 }
873
874 /**
875 * Removes the stack it from its current parent, so it can be either destroyed completely or
876 * re-parented.
877 */
878 void onRemovedFromDisplay() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700879 mDisplayContent.mDimLayerController.removeDimLayerUser(this);
Craig Mautnerdf88d732014-01-27 09:21:32 -0800880 EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
Wale Ogunwale10124582016-09-15 20:25:50 -0700881
882 if (mAnimationBackgroundSurface != null) {
883 mAnimationBackgroundSurface.destroySurface();
884 mAnimationBackgroundSurface = null;
885 }
Wale Ogunwale10124582016-09-15 20:25:50 -0700886
887 if (mStackId == DOCKED_STACK_ID) {
Andrii Kulian839def92016-11-02 10:58:58 -0700888 mDisplayContent.mDividerControllerLocked.notifyDockedStackExistsChanged(false);
Wale Ogunwale10124582016-09-15 20:25:50 -0700889 }
Andrii Kulian839def92016-11-02 10:58:58 -0700890
891 mDisplayContent = null;
892 mService.mWindowPlacerLocked.requestTraversal();
Craig Mautner00af9fe2013-03-25 09:13:41 -0700893 }
894
Craig Mautner05d29032013-05-03 13:40:13 -0700895 void resetAnimationBackgroundAnimator() {
896 mAnimationBackgroundAnimator = null;
897 mAnimationBackgroundSurface.hide();
898 }
899
Craig Mautner05d29032013-05-03 13:40:13 -0700900 void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
901 int animLayer = winAnimator.mAnimLayer;
902 if (mAnimationBackgroundAnimator == null
903 || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
904 mAnimationBackgroundAnimator = winAnimator;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700905 animLayer = mDisplayContent.getLayerForAnimationBackground(winAnimator);
906 mAnimationBackgroundSurface.show(animLayer - LAYER_OFFSET_DIM,
Craig Mautner05d29032013-05-03 13:40:13 -0700907 ((color >> 24) & 0xff) / 255f, 0);
908 }
909 }
910
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700911 // TODO: Should each user have there own stacks?
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000912 @Override
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800913 void switchUser() {
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000914 super.switchUser();
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700915 int top = mChildren.size();
Craig Mautnerac6f8432013-07-17 13:24:59 -0700916 for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700917 Task task = mChildren.get(taskNdx);
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700918 if (mService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700919 mChildren.remove(taskNdx);
920 mChildren.add(task);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700921 --top;
922 }
923 }
924 }
925
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800926 /**
927 * Adjusts the stack bounds if the IME is visible.
928 *
929 * @param imeWin The IME window.
930 */
Keisuke Kuroyanagi19d9a8f2016-05-12 16:49:02 -0700931 void setAdjustedForIme(WindowState imeWin, boolean forceUpdate) {
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800932 mImeWin = imeWin;
Chong Zhangbaba7832016-03-24 10:21:26 -0700933 mImeGoingAway = false;
Keisuke Kuroyanagi19d9a8f2016-05-12 16:49:02 -0700934 if (!mAdjustedForIme || forceUpdate) {
Jorim Jaggiff71d202016-04-14 13:12:36 -0700935 mAdjustedForIme = true;
936 mAdjustImeAmount = 0f;
Chong Zhangf347ab52016-04-18 21:02:01 -0700937 mAdjustDividerAmount = 0f;
938 updateAdjustForIme(0f, 0f, true /* force */);
Jorim Jaggiff71d202016-04-14 13:12:36 -0700939 }
Chong Zhangbaba7832016-03-24 10:21:26 -0700940 }
941
942 boolean isAdjustedForIme() {
Chong Zhang5117e272016-05-03 12:47:34 -0700943 return mAdjustedForIme;
Chong Zhangbaba7832016-03-24 10:21:26 -0700944 }
Chong Zhangbaba7832016-03-24 10:21:26 -0700945
946 boolean isAnimatingForIme() {
947 return mImeWin != null && mImeWin.isAnimatingLw();
948 }
949
950 /**
951 * Update the stack's bounds (crop or position) according to the IME window's
952 * current position. When IME window is animated, the bottom stack is animated
953 * together to track the IME window's current position, and the top stack is
954 * cropped as necessary.
955 *
956 * @return true if a traversal should be performed after the adjustment.
957 */
Chong Zhangf347ab52016-04-18 21:02:01 -0700958 boolean updateAdjustForIme(float adjustAmount, float adjustDividerAmount, boolean force) {
959 if (adjustAmount != mAdjustImeAmount
960 || adjustDividerAmount != mAdjustDividerAmount || force) {
Jorim Jaggieb88d832016-04-13 20:17:43 -0700961 mAdjustImeAmount = adjustAmount;
Chong Zhangf347ab52016-04-18 21:02:01 -0700962 mAdjustDividerAmount = adjustDividerAmount;
Jorim Jaggieb88d832016-04-13 20:17:43 -0700963 updateAdjustedBounds();
Jorim Jaggife762342016-10-13 14:33:27 +0200964 return isVisible();
Jorim Jaggieb88d832016-04-13 20:17:43 -0700965 } else {
966 return false;
Chong Zhangb58bbcc2016-03-23 11:57:36 -0700967 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800968 }
969
970 /**
971 * Resets the adjustment after it got adjusted for the IME.
Chong Zhangbaba7832016-03-24 10:21:26 -0700972 * @param adjustBoundsNow if true, reset and update the bounds immediately and forget about
973 * animations; otherwise, set flag and animates the window away together
974 * with IME window.
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800975 */
Chong Zhangbaba7832016-03-24 10:21:26 -0700976 void resetAdjustedForIme(boolean adjustBoundsNow) {
977 if (adjustBoundsNow) {
978 mImeWin = null;
979 mAdjustedForIme = false;
980 mImeGoingAway = false;
Jorim Jaggieb88d832016-04-13 20:17:43 -0700981 mAdjustImeAmount = 0f;
Chong Zhangf347ab52016-04-18 21:02:01 -0700982 mAdjustDividerAmount = 0f;
Chong Zhangbaba7832016-03-24 10:21:26 -0700983 updateAdjustedBounds();
Chong Zhang198afac2016-04-15 12:03:11 -0700984 mService.setResizeDimLayer(false, mStackId, 1.0f);
Chong Zhangbaba7832016-03-24 10:21:26 -0700985 } else {
986 mImeGoingAway |= mAdjustedForIme;
Chong Zhangb58bbcc2016-03-23 11:57:36 -0700987 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800988 }
989
990 /**
991 * Sets the amount how much we currently minimize our stack.
992 *
993 * @param minimizeAmount The amount, between 0 and 1.
994 * @return Whether the amount has changed and a layout is needed.
995 */
996 boolean setAdjustedForMinimizedDock(float minimizeAmount) {
997 if (minimizeAmount != mMinimizeAmount) {
998 mMinimizeAmount = minimizeAmount;
999 updateAdjustedBounds();
Jorim Jaggife762342016-10-13 14:33:27 +02001000 return isVisible();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001001 } else {
1002 return false;
1003 }
1004 }
1005
Matthew Nge15352e2016-12-20 15:36:29 -08001006 boolean shouldIgnoreInput() {
1007 return isAdjustedForMinimizedDockedStack() || mStackId == DOCKED_STACK_ID &&
1008 isMinimizedDockAndHomeStackResizable();
Jorim Jaggi409635b2016-04-01 15:32:28 -07001009 }
1010
Jorim Jaggiff71d202016-04-14 13:12:36 -07001011 /**
1012 * Puts all visible tasks that are adjusted for IME into resizing mode and adds the windows
1013 * to the list of to be drawn windows the service is waiting for.
1014 */
1015 void beginImeAdjustAnimation() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001016 for (int j = mChildren.size() - 1; j >= 0; j--) {
1017 final Task task = mChildren.get(j);
Wale Ogunwale44f21802016-09-02 12:49:48 -07001018 if (task.hasContentToDisplay()) {
Jorim Jaggiff71d202016-04-14 13:12:36 -07001019 task.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001020 task.setWaitingForDrawnIfResizingChanged();
Jorim Jaggiff71d202016-04-14 13:12:36 -07001021 }
1022 }
1023 }
1024
1025 /**
1026 * Resets the resizing state of all windows.
1027 */
1028 void endImeAdjustAnimation() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001029 for (int j = mChildren.size() - 1; j >= 0; j--) {
1030 mChildren.get(j).setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
Jorim Jaggiff71d202016-04-14 13:12:36 -07001031 }
1032 }
1033
Chong Zhang198afac2016-04-15 12:03:11 -07001034 int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
1035 return displayContentRect.top + (int)
1036 ((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN);
1037 }
1038
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001039 private boolean adjustForIME(final WindowState imeWin) {
1040 final int dockedSide = getDockSide();
1041 final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001042 if (imeWin == null || !dockedTopOrBottom) {
1043 return false;
1044 }
1045
1046 final Rect displayContentRect = mTmpRect;
1047 final Rect contentBounds = mTmpRect2;
1048
1049 // Calculate the content bounds excluding the area occupied by IME
1050 getDisplayContent().getContentRect(displayContentRect);
1051 contentBounds.set(displayContentRect);
Jorim Jaggi5ac2ba22016-04-11 21:14:12 -07001052 int imeTop = Math.max(imeWin.getFrameLw().top, contentBounds.top);
Chong Zhangbaba7832016-03-24 10:21:26 -07001053
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001054 imeTop += imeWin.getGivenContentInsetsLw().top;
1055 if (contentBounds.bottom > imeTop) {
1056 contentBounds.bottom = imeTop;
1057 }
1058
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001059 final int yOffset = displayContentRect.bottom - contentBounds.bottom;
1060
Chong Zhang198afac2016-04-15 12:03:11 -07001061 final int dividerWidth =
1062 getDisplayContent().mDividerControllerLocked.getContentWidth();
1063 final int dividerWidthInactive =
1064 getDisplayContent().mDividerControllerLocked.getContentWidthInactive();
1065
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001066 if (dockedSide == DOCKED_TOP) {
1067 // If this stack is docked on top, we make it smaller so the bottom stack is not
Chong Zhang198afac2016-04-15 12:03:11 -07001068 // occluded by IME. We shift its bottom up by the height of the IME, but
1069 // leaves at least 30% of the top stack visible.
1070 final int minTopStackBottom =
1071 getMinTopStackBottom(displayContentRect, mBounds.bottom);
1072 final int bottom = Math.max(
1073 mBounds.bottom - yOffset + dividerWidth - dividerWidthInactive,
1074 minTopStackBottom);
Jorim Jaggieb88d832016-04-13 20:17:43 -07001075 mTmpAdjustedBounds.set(mBounds);
1076 mTmpAdjustedBounds.bottom =
1077 (int) (mAdjustImeAmount * bottom + (1 - mAdjustImeAmount) * mBounds.bottom);
1078 mFullyAdjustedImeBounds.set(mBounds);
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001079 } else {
Chong Zhangf347ab52016-04-18 21:02:01 -07001080 // When the stack is on bottom and has no focus, it's only adjusted for divider width.
1081 final int dividerWidthDelta = dividerWidthInactive - dividerWidth;
1082
1083 // When the stack is on bottom and has focus, it needs to be moved up so as to
1084 // not occluded by IME, and at the same time adjusted for divider width.
1085 // We try to move it up by the height of the IME window, but only to the extent
1086 // that leaves at least 30% of the top stack visible.
1087 // 'top' is where the top of bottom stack will move to in this case.
1088 final int topBeforeImeAdjust = mBounds.top - dividerWidth + dividerWidthInactive;
1089 final int minTopStackBottom =
1090 getMinTopStackBottom(displayContentRect, mBounds.top - dividerWidth);
1091 final int top = Math.max(
1092 mBounds.top - yOffset, minTopStackBottom + dividerWidthInactive);
Chong Zhang198afac2016-04-15 12:03:11 -07001093
Jorim Jaggieb88d832016-04-13 20:17:43 -07001094 mTmpAdjustedBounds.set(mBounds);
Chong Zhangf347ab52016-04-18 21:02:01 -07001095 // Account for the adjustment for IME and divider width separately.
1096 // (top - topBeforeImeAdjust) is the amount of movement due to IME only,
1097 // and dividerWidthDelta is due to divider width change only.
1098 mTmpAdjustedBounds.top = mBounds.top +
1099 (int) (mAdjustImeAmount * (top - topBeforeImeAdjust) +
1100 mAdjustDividerAmount * dividerWidthDelta);
Jorim Jaggieb88d832016-04-13 20:17:43 -07001101 mFullyAdjustedImeBounds.set(mBounds);
1102 mFullyAdjustedImeBounds.top = top;
1103 mFullyAdjustedImeBounds.bottom = top + mBounds.height();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001104 }
1105 return true;
1106 }
1107
1108 private boolean adjustForMinimizedDockedStack(float minimizeAmount) {
1109 final int dockSide = getDockSide();
1110 if (dockSide == DOCKED_INVALID && !mTmpAdjustedBounds.isEmpty()) {
1111 return false;
1112 }
1113
1114 if (dockSide == DOCKED_TOP) {
Winson Chung303c6b72016-10-24 17:12:49 -07001115 mService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001116 int topInset = mTmpRect.top;
1117 mTmpAdjustedBounds.set(mBounds);
1118 mTmpAdjustedBounds.bottom =
1119 (int) (minimizeAmount * topInset + (1 - minimizeAmount) * mBounds.bottom);
1120 } else if (dockSide == DOCKED_LEFT) {
1121 mTmpAdjustedBounds.set(mBounds);
Jorim Jaggibcff1432016-04-01 15:49:45 -07001122 final int width = mBounds.width();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001123 mTmpAdjustedBounds.right =
1124 (int) (minimizeAmount * mDockedStackMinimizeThickness
1125 + (1 - minimizeAmount) * mBounds.right);
Jorim Jaggibcff1432016-04-01 15:49:45 -07001126 mTmpAdjustedBounds.left = mTmpAdjustedBounds.right - width;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001127 } else if (dockSide == DOCKED_RIGHT) {
1128 mTmpAdjustedBounds.set(mBounds);
1129 mTmpAdjustedBounds.left =
1130 (int) (minimizeAmount * (mBounds.right - mDockedStackMinimizeThickness)
1131 + (1 - minimizeAmount) * mBounds.left);
1132 }
1133 return true;
1134 }
1135
Matthew Nge15352e2016-12-20 15:36:29 -08001136 private boolean isMinimizedDockAndHomeStackResizable() {
1137 return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
1138 && mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
1139 }
1140
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001141 /**
Jorim Jaggif97ed922016-02-18 18:57:07 -08001142 * @return the distance in pixels how much the stack gets minimized from it's original size
1143 */
1144 int getMinimizeDistance() {
1145 final int dockSide = getDockSide();
1146 if (dockSide == DOCKED_INVALID) {
1147 return 0;
1148 }
1149
1150 if (dockSide == DOCKED_TOP) {
Winson Chung303c6b72016-10-24 17:12:49 -07001151 mService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
Jorim Jaggif97ed922016-02-18 18:57:07 -08001152 int topInset = mTmpRect.top;
1153 return mBounds.bottom - topInset;
1154 } else if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
1155 return mBounds.width() - mDockedStackMinimizeThickness;
1156 } else {
1157 return 0;
1158 }
1159 }
1160
1161 /**
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001162 * Updates the adjustment depending on it's current state.
1163 */
Chong Zhang5117e272016-05-03 12:47:34 -07001164 private void updateAdjustedBounds() {
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001165 boolean adjust = false;
1166 if (mMinimizeAmount != 0f) {
1167 adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
1168 } else if (mAdjustedForIme) {
1169 adjust = adjustForIME(mImeWin);
1170 }
1171 if (!adjust) {
1172 mTmpAdjustedBounds.setEmpty();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001173 }
Jorim Jaggieb88d832016-04-13 20:17:43 -07001174 setAdjustedBounds(mTmpAdjustedBounds);
Chong Zhang198afac2016-04-15 12:03:11 -07001175
Chong Zhangb8da4a72016-05-17 15:07:26 -07001176 final boolean isImeTarget = (mService.getImeFocusStackLocked() == this);
Chong Zhangf347ab52016-04-18 21:02:01 -07001177 if (mAdjustedForIme && adjust && !isImeTarget) {
1178 final float alpha = Math.max(mAdjustImeAmount, mAdjustDividerAmount)
1179 * IME_ADJUST_DIM_AMOUNT;
Chong Zhang198afac2016-04-15 12:03:11 -07001180 mService.setResizeDimLayer(true, mStackId, alpha);
1181 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001182 }
1183
Chong Zhang5117e272016-05-03 12:47:34 -07001184 void applyAdjustForImeIfNeeded(Task task) {
1185 if (mMinimizeAmount != 0f || !mAdjustedForIme || mAdjustedBounds.isEmpty()) {
1186 return;
1187 }
1188
1189 final Rect insetBounds = mImeGoingAway ? mBounds : mFullyAdjustedImeBounds;
1190 task.alignToAdjustedBounds(mAdjustedBounds, insetBounds, getDockSide() == DOCKED_TOP);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001191 mDisplayContent.setLayoutNeeded();
Chong Zhang5117e272016-05-03 12:47:34 -07001192 }
1193
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001194 boolean isAdjustedForMinimizedDockedStack() {
1195 return mMinimizeAmount != 0f;
1196 }
1197
Craig Mautner00af9fe2013-03-25 09:13:41 -07001198 public void dump(String prefix, PrintWriter pw) {
Wale Ogunwaleb429e682016-01-06 12:36:34 -08001199 pw.println(prefix + "mStackId=" + mStackId);
Wale Ogunwale10124582016-09-15 20:25:50 -07001200 pw.println(prefix + "mDeferRemoval=" + mDeferRemoval);
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001201 pw.println(prefix + "mFillsParent=" + mFillsParent);
Wale Ogunwaleb429e682016-01-06 12:36:34 -08001202 pw.println(prefix + "mBounds=" + mBounds.toShortString());
Jorim Jaggiaf558e12016-04-27 22:56:56 -07001203 if (mMinimizeAmount != 0f) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001204 pw.println(prefix + "mMinimizeAmount=" + mMinimizeAmount);
Jorim Jaggiaf558e12016-04-27 22:56:56 -07001205 }
1206 if (mAdjustedForIme) {
1207 pw.println(prefix + "mAdjustedForIme=true");
1208 pw.println(prefix + "mAdjustImeAmount=" + mAdjustImeAmount);
1209 pw.println(prefix + "mAdjustDividerAmount=" + mAdjustDividerAmount);
1210 }
Jorim Jaggieb88d832016-04-13 20:17:43 -07001211 if (!mAdjustedBounds.isEmpty()) {
1212 pw.println(prefix + "mAdjustedBounds=" + mAdjustedBounds.toShortString());
1213 }
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001214 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
1215 mChildren.get(taskNdx).dump(prefix + " ", pw);
Craig Mautner00af9fe2013-03-25 09:13:41 -07001216 }
Craig Mautner05d29032013-05-03 13:40:13 -07001217 if (mAnimationBackgroundSurface.isDimming()) {
Wale Ogunwaleb429e682016-01-06 12:36:34 -08001218 pw.println(prefix + "mWindowAnimationBackgroundSurface:");
Craig Mautner05d29032013-05-03 13:40:13 -07001219 mAnimationBackgroundSurface.printTo(prefix + " ", pw);
1220 }
Craig Mautnerdc548482014-02-05 13:35:24 -08001221 if (!mExitingAppTokens.isEmpty()) {
1222 pw.println();
1223 pw.println(" Exiting application tokens:");
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001224 for (int i = mExitingAppTokens.size() - 1; i >= 0; i--) {
Craig Mautnerdc548482014-02-05 13:35:24 -08001225 WindowToken token = mExitingAppTokens.get(i);
1226 pw.print(" Exiting App #"); pw.print(i);
1227 pw.print(' '); pw.print(token);
1228 pw.println(':');
1229 token.dump(pw, " ");
1230 }
1231 }
Craig Mautner00af9fe2013-03-25 09:13:41 -07001232 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001233
Wale Ogunwalef175e8a2015-09-29 11:07:06 -07001234 /** Fullscreen status of the stack without adjusting for other factors in the system like
1235 * visibility of docked stack.
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001236 * Most callers should be using {@link #fillsParent} as it take into consideration other
Wale Ogunwalef175e8a2015-09-29 11:07:06 -07001237 * system factors. */
1238 boolean getRawFullscreen() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001239 return mFillsParent;
Wale Ogunwalef175e8a2015-09-29 11:07:06 -07001240 }
1241
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001242 @Override
Wale Ogunwale29bfbb82016-05-12 15:13:52 -07001243 public boolean dimFullscreen() {
Matthew Ngae1ff4f2016-11-10 15:49:14 -08001244 return StackId.isHomeOrRecentsStack(mStackId) || fillsParent();
Wale Ogunwale29bfbb82016-05-12 15:13:52 -07001245 }
1246
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001247 @Override
1248 boolean fillsParent() {
Wale Ogunwalef175e8a2015-09-29 11:07:06 -07001249 if (useCurrentBounds()) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001250 return mFillsParent;
Wale Ogunwalef175e8a2015-09-29 11:07:06 -07001251 }
1252 // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
1253 // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
1254 // system.
1255 return true;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001256 }
1257
1258 @Override
1259 public DisplayInfo getDisplayInfo() {
1260 return mDisplayContent.getDisplayInfo();
1261 }
1262
1263 @Override
Wale Ogunwalef0a60a92017-01-19 09:44:40 -08001264 public boolean isAttachedToDisplay() {
1265 return mDisplayContent != null;
1266 }
1267
1268 @Override
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001269 public String toString() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001270 return "{stackId=" + mStackId + " tasks=" + mChildren + "}";
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001271 }
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001272
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001273 String getName() {
1274 return toShortString();
1275 }
1276
Filip Gruszczynski0689ae92015-10-01 12:30:31 -07001277 @Override
1278 public String toShortString() {
1279 return "Stack=" + mStackId;
1280 }
1281
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001282 /**
Chong Zhangc806d902015-11-30 09:44:27 -08001283 * For docked workspace (or workspace that's side-by-side to the docked), provides
1284 * information which side of the screen was the dock anchored.
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001285 */
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001286 int getDockSide() {
Jorim Jaggi737af722015-12-31 10:42:27 +01001287 return getDockSide(mBounds);
1288 }
1289
1290 int getDockSide(Rect bounds) {
Chong Zhangc806d902015-11-30 09:44:27 -08001291 if (mStackId != DOCKED_STACK_ID && !StackId.isResizeableByDockedStack(mStackId)) {
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001292 return DOCKED_INVALID;
1293 }
1294 if (mDisplayContent == null) {
1295 return DOCKED_INVALID;
1296 }
1297 mDisplayContent.getLogicalDisplayRect(mTmpRect);
Andrii Kulian441e4492016-09-29 15:25:00 -07001298 final int orientation = mDisplayContent.getConfiguration().orientation;
Jorim Jaggi85639432016-05-06 17:27:55 -07001299 return getDockSideUnchecked(bounds, mTmpRect, orientation);
1300 }
1301
1302 static int getDockSideUnchecked(Rect bounds, Rect displayRect, int orientation) {
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001303 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
1304 // Portrait mode, docked either at the top or the bottom.
Jorim Jaggi85639432016-05-06 17:27:55 -07001305 if (bounds.top - displayRect.top <= displayRect.bottom - bounds.bottom) {
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001306 return DOCKED_TOP;
1307 } else {
1308 return DOCKED_BOTTOM;
1309 }
1310 } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
1311 // Landscape mode, docked either on the left or on the right.
Jorim Jaggi85639432016-05-06 17:27:55 -07001312 if (bounds.left - displayRect.left <= displayRect.right - bounds.right) {
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001313 return DOCKED_LEFT;
1314 } else {
1315 return DOCKED_RIGHT;
1316 }
1317 } else {
1318 return DOCKED_INVALID;
1319 }
1320 }
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -07001321
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001322 boolean hasTaskForUser(int userId) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001323 for (int i = mChildren.size() - 1; i >= 0; i--) {
1324 final Task task = mChildren.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001325 if (task.mUserId == userId) {
1326 return true;
1327 }
1328 }
1329 return false;
1330 }
1331
1332 int taskIdFromPoint(int x, int y) {
1333 getBounds(mTmpRect);
1334 if (!mTmpRect.contains(x, y) || isAdjustedForMinimizedDockedStack()) {
1335 return -1;
1336 }
1337
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001338 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
1339 final Task task = mChildren.get(taskNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001340 final WindowState win = task.getTopVisibleAppMainWindow();
1341 if (win == null) {
1342 continue;
1343 }
1344 // We need to use the task's dim bounds (which is derived from the visible bounds of its
1345 // apps windows) for any touch-related tests. Can't use the task's original bounds
1346 // because it might be adjusted to fit the content frame. For example, the presence of
1347 // the IME adjusting the windows frames when the app window is the IME target.
1348 task.getDimBounds(mTmpRect);
1349 if (mTmpRect.contains(x, y)) {
1350 return task.mTaskId;
1351 }
1352 }
1353
1354 return -1;
1355 }
1356
1357 void findTaskForResizePoint(int x, int y, int delta,
1358 DisplayContent.TaskForResizePointSearchResult results) {
1359 if (!StackId.isTaskResizeAllowed(mStackId)) {
1360 results.searchDone = true;
1361 return;
1362 }
1363
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001364 for (int i = mChildren.size() - 1; i >= 0; --i) {
1365 final Task task = mChildren.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001366 if (task.isFullscreen()) {
1367 results.searchDone = true;
1368 return;
1369 }
1370
1371 // We need to use the task's dim bounds (which is derived from the visible bounds of
1372 // its apps windows) for any touch-related tests. Can't use the task's original
1373 // bounds because it might be adjusted to fit the content frame. One example is when
1374 // the task is put to top-left quadrant, the actual visible area would not start at
1375 // (0,0) after it's adjusted for the status bar.
1376 task.getDimBounds(mTmpRect);
1377 mTmpRect.inset(-delta, -delta);
1378 if (mTmpRect.contains(x, y)) {
1379 mTmpRect.inset(delta, delta);
1380
1381 results.searchDone = true;
1382
1383 if (!mTmpRect.contains(x, y)) {
1384 results.taskForResize = task;
1385 return;
1386 }
1387 // User touched inside the task. No need to look further,
1388 // focus transfer will be handled in ACTION_UP.
1389 return;
1390 }
1391 }
1392 }
1393
1394 void setTouchExcludeRegion(Task focusedTask, int delta, Region touchExcludeRegion,
1395 Rect contentRect, Rect postExclude) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001396 for (int i = mChildren.size() - 1; i >= 0; --i) {
1397 final Task task = mChildren.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001398 AppWindowToken token = task.getTopVisibleAppToken();
1399 if (token == null || !token.hasContentToDisplay()) {
1400 continue;
1401 }
1402
1403 /**
1404 * Exclusion region is the region that TapDetector doesn't care about.
1405 * Here we want to remove all non-focused tasks from the exclusion region.
1406 * We also remove the outside touch area for resizing for all freeform
1407 * tasks (including the focused).
1408 *
1409 * We save the focused task region once we find it, and add it back at the end.
Matthew Nge15352e2016-12-20 15:36:29 -08001410 *
1411 * If the task is home stack and it is resizable in the minimized state, we want to
1412 * exclude the docked stack from touch so we need the entire screen area and not just a
1413 * small portion which the home stack currently is resized to.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001414 */
1415
Matthew Nge15352e2016-12-20 15:36:29 -08001416 if (task.isHomeTask() && isMinimizedDockAndHomeStackResizable()) {
1417 mDisplayContent.getLogicalDisplayRect(mTmpRect);
1418 } else {
1419 task.getDimBounds(mTmpRect);
1420 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001421
1422 if (task == focusedTask) {
1423 // Add the focused task rect back into the exclude region once we are done
1424 // processing stacks.
1425 postExclude.set(mTmpRect);
1426 }
1427
1428 final boolean isFreeformed = task.inFreeformWorkspace();
1429 if (task != focusedTask || isFreeformed) {
1430 if (isFreeformed) {
1431 // If the task is freeformed, enlarge the area to account for outside
1432 // touch area for resize.
1433 mTmpRect.inset(-delta, -delta);
1434 // Intersect with display content rect. If we have system decor (status bar/
1435 // navigation bar), we want to exclude that from the tap detection.
1436 // Otherwise, if the app is partially placed under some system button (eg.
1437 // Recents, Home), pressing that button would cause a full series of
1438 // unwanted transfer focus/resume/pause, before we could go home.
1439 mTmpRect.intersect(contentRect);
1440 }
1441 touchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
1442 }
1443 }
1444 }
1445
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001446 @Override // AnimatesBounds
1447 public boolean setSize(Rect bounds) {
1448 synchronized (mService.mWindowMap) {
1449 if (mDisplayContent == null) {
1450 return false;
1451 }
1452 }
1453 try {
Wale Ogunwalee75a9ad2016-03-18 20:43:49 -07001454 mService.mActivityManager.resizeStack(mStackId, bounds, false, true, false, -1);
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001455 } catch (RemoteException e) {
1456 }
1457 return true;
1458 }
1459
Robert Carr0d00c2e2016-02-29 17:45:02 -08001460 public boolean setPinnedStackSize(Rect bounds, Rect tempTaskBounds) {
Robert Carr0d00c2e2016-02-29 17:45:02 -08001461 try {
1462 mService.mActivityManager.resizePinnedStack(bounds, tempTaskBounds);
1463 } catch (RemoteException e) {
1464 // I don't believe you.
1465 }
1466 return true;
1467 }
1468
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001469 @Override // AnimatesBounds
Robert Carr7e4c90e2017-02-15 19:52:38 -08001470 public void onAnimationStart(boolean toFullscreen) {
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001471 synchronized (mService.mWindowMap) {
Robert Carr1ca6a332016-04-11 18:00:43 -07001472 mBoundsAnimating = true;
Robert Carr7e4c90e2017-02-15 19:52:38 -08001473 mBoundsAnimatingToFullscreen = toFullscreen;
Wale Ogunwalece144522016-02-05 22:51:01 -08001474 }
Winson Chung85d39982017-02-24 15:21:25 -08001475
1476 if (mStackId == PINNED_STACK_ID) {
1477 try {
1478 mService.mActivityManager.notifyPinnedStackAnimationStarted();
1479 } catch (RemoteException e) {
1480 // I don't believe you...
1481 }
1482 }
Wale Ogunwalece144522016-02-05 22:51:01 -08001483 }
1484
1485 @Override // AnimatesBounds
1486 public void onAnimationEnd() {
1487 synchronized (mService.mWindowMap) {
Robert Carr1ca6a332016-04-11 18:00:43 -07001488 mBoundsAnimating = false;
Wale Ogunwalece144522016-02-05 22:51:01 -08001489 mService.requestTraversal();
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001490 }
Winson Chung85d39982017-02-24 15:21:25 -08001491
Wale Ogunwale480dca02016-02-06 13:58:29 -08001492 if (mStackId == PINNED_STACK_ID) {
1493 try {
1494 mService.mActivityManager.notifyPinnedStackAnimationEnded();
1495 } catch (RemoteException e) {
1496 // I don't believe you...
1497 }
1498 }
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001499 }
Filip Gruszczynskic17d8b72016-02-03 16:52:59 -08001500
1501 @Override
1502 public void moveToFullscreen() {
1503 try {
1504 mService.mActivityManager.moveTasksToFullscreenStack(mStackId, true);
1505 } catch (RemoteException e) {
1506 e.printStackTrace();
1507 }
1508 }
1509
Robert Carrc7294602016-05-13 11:32:05 -07001510 public boolean hasMovementAnimations() {
1511 return StackId.hasMovementAnimations(mStackId);
Robert Carr0d00c2e2016-02-29 17:45:02 -08001512 }
1513
Robert Carr8f0a3ad2017-02-15 19:30:28 -08001514 public boolean isForceScaled() {
Robert Carr1ca6a332016-04-11 18:00:43 -07001515 return mBoundsAnimating;
1516 }
1517
1518 public boolean getBoundsAnimating() {
1519 return mBoundsAnimating;
Robert Carr0d00c2e2016-02-29 17:45:02 -08001520 }
Jorim Jaggi6626f542016-08-22 13:08:44 -07001521
Robert Carr7e4c90e2017-02-15 19:52:38 -08001522 public boolean isBoundsAnimatingToFullscreen() {
1523 return mBoundsAnimating && mBoundsAnimatingToFullscreen;
1524 }
1525
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001526 /** Returns true if a removal action is still being deferred. */
1527 boolean checkCompleteDeferredRemoval() {
1528 if (isAnimating()) {
1529 return true;
1530 }
Wale Ogunwale10124582016-09-15 20:25:50 -07001531 if (mDeferRemoval) {
1532 removeImmediately();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001533 }
1534
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001535 return super.checkCompleteDeferredRemoval();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001536 }
1537
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001538 void stepAppWindowsAnimation(long currentTime) {
1539 super.stepAppWindowsAnimation(currentTime);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001540
1541 // TODO: Why aren't we just using the loop above for this? mAppAnimator.animating isn't set
1542 // below but is set in the loop above. See if it really matters...
1543 final int exitingCount = mExitingAppTokens.size();
1544 for (int i = 0; i < exitingCount; i++) {
1545 final AppWindowAnimator appAnimator = mExitingAppTokens.get(i).mAppAnimator;
1546 appAnimator.wasAnimating = appAnimator.animating;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001547 if (appAnimator.stepAnimationLocked(currentTime)) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001548 mService.mAnimator.setAnimating(true);
1549 mService.mAnimator.mAppWindowAnimating = true;
1550 } else if (appAnimator.wasAnimating) {
1551 // stopped animating, do one more pass through the layout
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001552 appAnimator.mAppToken.setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
1553 "exiting appToken " + appAnimator.mAppToken + " done");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001554 if (DEBUG_ANIM) Slog.v(TAG_WM,
1555 "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken);
1556 }
1557 }
1558 }
1559
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001560 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07001561 int getOrientation() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001562 return (StackId.canSpecifyOrientation(mStackId))
1563 ? super.getOrientation() : SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001564 }
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -08001565}