blob: 76c9c262cd76262f78beef4a757b2fdf9cccaff9 [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
Matthew Ngbf155872017-10-27 15:24:39 -070019import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
Vishnu Nair04ab4392018-01-10 11:00:06 -080020import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Wale Ogunwale68278562017-09-23 17:13:55 -070021import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
22import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
23import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
Robert Carr32bcb102018-01-29 15:03:23 -080024import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
Wale Ogunwale68278562017-09-23 17:13:55 -070025import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
Wale Ogunwale51362492016-09-08 17:49:17 -070026import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070027import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
28import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
Winson Chung303c6b72016-10-24 17:12:49 -070029import static android.view.Display.DEFAULT_DISPLAY;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070030import static android.view.WindowManager.DOCKED_BOTTOM;
31import static android.view.WindowManager.DOCKED_INVALID;
32import static android.view.WindowManager.DOCKED_LEFT;
33import static android.view.WindowManager.DOCKED_RIGHT;
34import static android.view.WindowManager.DOCKED_TOP;
Jorim Jaggiff71d202016-04-14 13:12:36 -070035import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070036import static com.android.server.wm.StackProto.ADJUSTED_BOUNDS;
37import static com.android.server.wm.StackProto.ADJUSTED_FOR_IME;
38import static com.android.server.wm.StackProto.ADJUST_DIVIDER_AMOUNT;
39import static com.android.server.wm.StackProto.ADJUST_IME_AMOUNT;
Winson Chung82267ce2018-04-06 16:38:26 -070040import static com.android.server.wm.StackProto.ANIMATING_BOUNDS;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070041import static com.android.server.wm.StackProto.ANIMATION_BACKGROUND_SURFACE_IS_DIMMING;
42import static com.android.server.wm.StackProto.BOUNDS;
43import static com.android.server.wm.StackProto.DEFER_REMOVAL;
44import static com.android.server.wm.StackProto.FILLS_PARENT;
45import static com.android.server.wm.StackProto.ID;
46import static com.android.server.wm.StackProto.MINIMIZE_AMOUNT;
47import static com.android.server.wm.StackProto.TASKS;
48import static com.android.server.wm.StackProto.WINDOW_CONTAINER;
Winson Chung6a38fca2018-03-28 17:57:09 -070049import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
50import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Jorim Jaggi2917dc42016-04-11 11:39:13 -070051
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070052import android.annotation.CallSuper;
Wale Ogunwale60454db2015-01-23 16:05:07 -080053import android.content.res.Configuration;
chaviw3e751af2018-01-11 11:22:39 -080054import android.graphics.Point;
Craig Mautner05d29032013-05-03 13:40:13 -070055import android.graphics.Rect;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -070056import android.graphics.Region;
Filip Gruszczynski84fa3352016-01-25 16:28:49 -080057import android.os.RemoteException;
Robert Carr32bcb102018-01-29 15:03:23 -080058import android.util.DisplayMetrics;
Craig Mautner2c2549c2013-11-12 08:31:15 -080059import android.util.EventLog;
Craig Mautnerf0ac5c82013-06-24 11:21:57 -070060import android.util.Slog;
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -070061import android.util.SparseArray;
Steven Timotiusaf03df62017-07-18 16:56:43 -070062import android.util.proto.ProtoOutputStream;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -070063import android.view.DisplayInfo;
Wale Ogunwale94744212015-09-21 19:01:47 -070064import android.view.Surface;
Robert Carrf59b8dd2017-10-02 18:58:36 -070065import android.view.SurfaceControl;
Jorim Jaggi737af722015-12-31 10:42:27 +010066import com.android.internal.policy.DividerSnapAlgorithm;
67import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
68import com.android.internal.policy.DockedDividerUtils;
Craig Mautner2c2549c2013-11-12 08:31:15 -080069import com.android.server.EventLogTags;
Craig Mautner00af9fe2013-03-25 09:13:41 -070070import java.io.PrintWriter;
Craig Mautnerc00204b2013-03-05 15:02:14 -080071
Robert Carrf59b8dd2017-10-02 18:58:36 -070072public class TaskStack extends WindowContainer<Task> implements
Winson Chung8bca9e42017-04-16 15:59:43 -070073 BoundsAnimationTarget {
Chong Zhang198afac2016-04-15 12:03:11 -070074 /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
75 * restrict IME adjustment so that a min portion of top stack remains visible.*/
76 private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f;
77
78 /** Dimming amount for non-focused stack when stacks are IME-adjusted. */
79 private static final float IME_ADJUST_DIM_AMOUNT = 0.25f;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -070080
Craig Mautner00af9fe2013-03-25 09:13:41 -070081 /** Unique identifier */
Craig Mautnerc00204b2013-03-05 15:02:14 -080082 final int mStackId;
Craig Mautner00af9fe2013-03-25 09:13:41 -070083
84 /** The display this stack sits under. */
Wale Ogunwale14a3fb92016-09-11 15:19:05 -070085 // TODO: Track parent marks like this in WindowContainer.
Craig Mautnerdf88d732014-01-27 09:21:32 -080086 private DisplayContent mDisplayContent;
Craig Mautner00af9fe2013-03-25 09:13:41 -070087
Craig Mautnerb660b9d2014-02-13 10:59:16 -080088 /** For comparison with DisplayContent bounds. */
89 private Rect mTmpRect = new Rect();
Wale Ogunwalee45899a2015-10-01 11:30:34 -070090 private Rect mTmpRect2 = new Rect();
Winson Chung19953ca2017-04-11 11:19:23 -070091 private Rect mTmpRect3 = new Rect();
Craig Mautnerb660b9d2014-02-13 10:59:16 -080092
Chong Zhangb816b862016-01-25 12:01:12 -080093 /** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
94 private final Rect mAdjustedBounds = new Rect();
95
Jorim Jaggieb88d832016-04-13 20:17:43 -070096 /**
97 * Fully adjusted IME bounds. These are different from {@link #mAdjustedBounds} because they
98 * represent the state when the animation has ended.
99 */
100 private final Rect mFullyAdjustedImeBounds = new Rect();
101
Wale Ogunwale94744212015-09-21 19:01:47 -0700102 // Device rotation as of the last time {@link #mBounds} was set.
Wale Ogunwale02319a62016-09-26 15:21:22 -0700103 private int mRotation;
Wale Ogunwale94744212015-09-21 19:01:47 -0700104
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700105 /** Density as of last time {@link #mBounds} was set. */
Wale Ogunwale02319a62016-09-26 15:21:22 -0700106 private int mDensity;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700107
Robert Carrf59b8dd2017-10-02 18:58:36 -0700108 private SurfaceControl mAnimationBackgroundSurface;
109 private boolean mAnimationBackgroundSurfaceIsShown = false;
Craig Mautner05d29032013-05-03 13:40:13 -0700110
111 /** The particular window with an Animation with non-zero background color. */
Wale Ogunwale02319a62016-09-26 15:21:22 -0700112 private WindowStateAnimator mAnimationBackgroundAnimator;
Craig Mautner05d29032013-05-03 13:40:13 -0700113
Craig Mautnerdc548482014-02-05 13:35:24 -0800114 /** Application tokens that are exiting, but still on screen for animations. */
115 final AppTokenList mExitingAppTokens = new AppTokenList();
Wale Ogunwale48458e12017-06-06 10:07:58 -0700116 final AppTokenList mTmpAppTokens = new AppTokenList();
Craig Mautnerdc548482014-02-05 13:35:24 -0800117
Craig Mautner95da1082014-02-24 17:54:35 -0800118 /** Detach this stack from its display when animation completes. */
Wale Ogunwalef6192862016-09-10 13:42:30 -0700119 // TODO: maybe tie this to WindowContainer#removeChild some how...
Wale Ogunwale10124582016-09-15 20:25:50 -0700120 boolean mDeferRemoval;
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800121
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800122 private final Rect mTmpAdjustedBounds = new Rect();
123 private boolean mAdjustedForIme;
Chong Zhangbaba7832016-03-24 10:21:26 -0700124 private boolean mImeGoingAway;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800125 private WindowState mImeWin;
126 private float mMinimizeAmount;
Jorim Jaggieb88d832016-04-13 20:17:43 -0700127 private float mAdjustImeAmount;
Chong Zhangf347ab52016-04-18 21:02:01 -0700128 private float mAdjustDividerAmount;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800129 private final int mDockedStackMinimizeThickness;
130
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700131 // If this is true, we are in the bounds animating mode. The task will be down or upscaled to
132 // perfectly fit the region it would have been cropped to. We may also avoid certain logic we
133 // would otherwise apply while resizing, while resizing in the bounds animating mode.
Robert Carr1ca6a332016-04-11 18:00:43 -0700134 private boolean mBoundsAnimating = false;
Winson Chung40a5f932017-04-13 16:39:36 -0700135 // Set when an animation has been requested but has not yet started from the UI thread. This is
136 // cleared when the animation actually starts.
137 private boolean mBoundsAnimatingRequested = false;
Robert Carr7e4c90e2017-02-15 19:52:38 -0800138 private boolean mBoundsAnimatingToFullscreen = false;
Winson Chung19953ca2017-04-11 11:19:23 -0700139 private boolean mCancelCurrentBoundsAnimation = false;
Winson Chung84a38342016-11-08 16:15:10 -0800140 private Rect mBoundsAnimationTarget = new Rect();
Winson Chung8bca9e42017-04-16 15:59:43 -0700141 private Rect mBoundsAnimationSourceHintBounds = new Rect();
Robert Carr0d00c2e2016-02-29 17:45:02 -0800142
Chong Zhang167bbfac2016-03-31 09:44:34 -0700143 // Temporary storage for the new bounds that should be used after the configuration change.
144 // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
145 private final Rect mBoundsAfterRotation = new Rect();
146
Robert Carr18f622f2017-05-08 11:20:43 -0700147 Rect mPreAnimationBounds = new Rect();
148
Robert Carrf59b8dd2017-10-02 18:58:36 -0700149 private Dimmer mDimmer = new Dimmer(this);
150
151 /**
152 * For {@link #prepareSurfaces}.
153 */
154 final Rect mTmpDimBoundsRect = new Rect();
chaviw3e751af2018-01-11 11:22:39 -0800155 private final Point mLastSurfaceSize = new Point();
Robert Carrf59b8dd2017-10-02 18:58:36 -0700156
Jorim Jaggi6de61012018-03-19 14:53:23 +0100157 private final AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry =
158 new AnimatingAppWindowTokenRegistry();
159
Wale Ogunwale704a3c02017-09-18 15:30:52 -0700160 TaskStack(WindowManagerService service, int stackId, StackWindowController controller) {
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100161 super(service);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800162 mStackId = stackId;
Wale Ogunwale704a3c02017-09-18 15:30:52 -0700163 setController(controller);
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800164 mDockedStackMinimizeThickness = service.mContext.getResources().getDimensionPixelSize(
165 com.android.internal.R.dimen.docked_stack_minimize_thickness);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700166 EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800167 }
168
169 DisplayContent getDisplayContent() {
170 return mDisplayContent;
171 }
172
Jorim Jaggid3ec5072016-04-28 15:57:47 -0700173 Task findHomeTask() {
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700174 if (!isActivityTypeHome() || mChildren.isEmpty()) {
Jorim Jaggid3ec5072016-04-28 15:57:47 -0700175 return null;
176 }
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700177 return mChildren.get(mChildren.size() - 1);
Wale Ogunwale15ead902016-09-02 14:30:11 -0700178 }
179
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700180 /**
181 * Set the bounds of the stack and its containing tasks.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700182 * @param stackBounds New stack bounds. Passing in null sets the bounds to fullscreen.
Filip Gruszczynskiebcc8752015-08-25 16:51:05 -0700183 * @param taskBounds Bounds for individual tasks, keyed by task id.
Bryce Leef3c6a472017-11-14 14:53:06 -0800184 * @param taskTempInsetBounds Inset bounds for individual tasks, keyed by task id.
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700185 * @return True if the stack bounds was changed.
186 * */
Wale Ogunwalea6e902e2015-09-21 18:37:15 -0700187 boolean setBounds(
Bryce Leef3c6a472017-11-14 14:53:06 -0800188 Rect stackBounds, SparseArray<Rect> taskBounds, SparseArray<Rect> taskTempInsetBounds) {
Jorim Jaggi899327f2016-02-25 20:44:18 -0500189 setBounds(stackBounds);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700190
191 // Update bounds of containing tasks.
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700192 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
193 final Task task = mChildren.get(taskNdx);
Bryce Leef3c6a472017-11-14 14:53:06 -0800194 task.setBounds(taskBounds.get(task.mTaskId), false /* forced */);
195 task.setTempInsetBounds(taskTempInsetBounds != null ?
196 taskTempInsetBounds.get(task.mTaskId) : null);
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700197 }
198 return true;
199 }
200
Jorim Jaggi0429f352015-12-22 16:29:16 +0100201 void prepareFreezingTaskBounds() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700202 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
203 final Task task = mChildren.get(taskNdx);
Jorim Jaggi0429f352015-12-22 16:29:16 +0100204 task.prepareFreezingBounds();
205 }
206 }
207
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800208 /**
209 * Overrides the adjusted bounds, i.e. sets temporary layout bounds which are different from
210 * the normal task bounds.
211 *
212 * @param bounds The adjusted bounds.
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800213 */
Jorim Jaggieb88d832016-04-13 20:17:43 -0700214 private void setAdjustedBounds(Rect bounds) {
215 if (mAdjustedBounds.equals(bounds) && !isAnimatingForIme()) {
216 return;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800217 }
218
219 mAdjustedBounds.set(bounds);
220 final boolean adjusted = !mAdjustedBounds.isEmpty();
Jorim Jaggieb88d832016-04-13 20:17:43 -0700221 Rect insetBounds = null;
Matthew Nge15352e2016-12-20 15:36:29 -0800222 if (adjusted && isAdjustedForMinimizedDockedStack()) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800223 insetBounds = getRawBounds();
Chong Zhang5117e272016-05-03 12:47:34 -0700224 } else if (adjusted && mAdjustedForIme) {
Jorim Jaggieb88d832016-04-13 20:17:43 -0700225 if (mImeGoingAway) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800226 insetBounds = getRawBounds();
Jorim Jaggieb88d832016-04-13 20:17:43 -0700227 } else {
228 insetBounds = mFullyAdjustedImeBounds;
229 }
230 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800231 alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : getRawBounds(), insetBounds);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700232 mDisplayContent.setLayoutNeeded();
chaviwe07246a2017-12-12 16:18:29 -0800233
234 updateSurfaceBounds();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800235 }
236
237 private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800238 if (matchParentBounds()) {
Chong Zhangb816b862016-01-25 12:01:12 -0800239 return;
240 }
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700241
242 final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
243
Chong Zhangb816b862016-01-25 12:01:12 -0800244 // Update bounds of containing tasks.
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700245 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
246 final Task task = mChildren.get(taskNdx);
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700247 task.alignToAdjustedBounds(adjustedBounds, tempInsetBounds, alignBottom);
Chong Zhangb816b862016-01-25 12:01:12 -0800248 }
249 }
250
Bryce Leef3c6a472017-11-14 14:53:06 -0800251 private void updateAnimationBackgroundBounds() {
Robert Carrf59b8dd2017-10-02 18:58:36 -0700252 if (mAnimationBackgroundSurface == null) {
253 return;
254 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800255 getRawBounds(mTmpRect);
chaviwe07246a2017-12-12 16:18:29 -0800256 final Rect stackBounds = getBounds();
257 getPendingTransaction()
258 .setSize(mAnimationBackgroundSurface, mTmpRect.width(), mTmpRect.height())
259 .setPosition(mAnimationBackgroundSurface, mTmpRect.left - stackBounds.left,
260 mTmpRect.top - stackBounds.top);
Robert Carrf59b8dd2017-10-02 18:58:36 -0700261 scheduleAnimation();
262 }
263
264 private void hideAnimationSurface() {
265 if (mAnimationBackgroundSurface == null) {
266 return;
267 }
268 getPendingTransaction().hide(mAnimationBackgroundSurface);
269 mAnimationBackgroundSurfaceIsShown = false;
270 scheduleAnimation();
271 }
272
273 private void showAnimationSurface(float alpha) {
274 if (mAnimationBackgroundSurface == null) {
275 return;
276 }
277 getPendingTransaction().setLayer(mAnimationBackgroundSurface, Integer.MIN_VALUE)
278 .setAlpha(mAnimationBackgroundSurface, alpha)
279 .show(mAnimationBackgroundSurface);
280 mAnimationBackgroundSurfaceIsShown = true;
281 scheduleAnimation();
282 }
283
Bryce Leef3c6a472017-11-14 14:53:06 -0800284 @Override
285 public int setBounds(Rect bounds) {
286 return setBounds(getOverrideBounds(), bounds);
287 }
288
289 private int setBounds(Rect existing, Rect bounds) {
Wale Ogunwale94744212015-09-21 19:01:47 -0700290 int rotation = Surface.ROTATION_0;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700291 int density = DENSITY_DPI_UNDEFINED;
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800292 if (mDisplayContent != null) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800293 mDisplayContent.getBounds(mTmpRect);
Wale Ogunwale94744212015-09-21 19:01:47 -0700294 rotation = mDisplayContent.getDisplayInfo().rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700295 density = mDisplayContent.getDisplayInfo().logicalDensityDpi;
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800296 }
297
Bryce Leef3c6a472017-11-14 14:53:06 -0800298 if (equivalentBounds(existing, bounds) && mRotation == rotation) {
299 return BOUNDS_CHANGE_NONE;
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800300 }
301
Bryce Leef3c6a472017-11-14 14:53:06 -0800302 final int result = super.setBounds(bounds);
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700303
Bryce Leef3c6a472017-11-14 14:53:06 -0800304 if (mDisplayContent != null) {
305 updateAnimationBackgroundBounds();
306 }
307
Wale Ogunwale94744212015-09-21 19:01:47 -0700308 mRotation = rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700309 mDensity = density;
Chong Zhangb816b862016-01-25 12:01:12 -0800310
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800311 updateAdjustedBounds();
Chong Zhangb816b862016-01-25 12:01:12 -0800312
chaviwe07246a2017-12-12 16:18:29 -0800313 updateSurfaceBounds();
Bryce Leef3c6a472017-11-14 14:53:06 -0800314 return result;
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800315 }
316
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700317 /** Bounds of the stack without adjusting for other factors in the system like visibility
318 * of docked stack.
Bryce Leef3c6a472017-11-14 14:53:06 -0800319 * Most callers should be using {@link ConfigurationContainer#getOverrideBounds} as it take into
320 * consideration other system factors. */
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700321 void getRawBounds(Rect out) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800322 out.set(getRawBounds());
323 }
324
325 Rect getRawBounds() {
326 return super.getBounds();
Craig Mautnerb660b9d2014-02-13 10:59:16 -0800327 }
328
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700329 /** Return true if the current bound can get outputted to the rest of the system as-is. */
330 private boolean useCurrentBounds() {
Bryce Leef3c6a472017-11-14 14:53:06 -0800331 if (matchParentBounds()
Wale Ogunwale926aade2017-08-29 11:24:37 -0700332 || !inSplitScreenSecondaryWindowingMode()
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700333 || mDisplayContent == null
chaviw23012112017-12-20 15:29:04 -0800334 || mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility() != null) {
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700335 return true;
336 }
337 return false;
338 }
339
Bryce Leef3c6a472017-11-14 14:53:06 -0800340 @Override
341 public void getBounds(Rect bounds) {
342 bounds.set(getBounds());
343 }
344
345 @Override
346 public Rect getBounds() {
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700347 if (useCurrentBounds()) {
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800348 // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
349 // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
350 // stack is visible since it is already what we want to represent to the rest of the
351 // system.
352 if (!mAdjustedBounds.isEmpty()) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800353 return mAdjustedBounds;
Chong Zhangb816b862016-01-25 12:01:12 -0800354 } else {
Bryce Leef3c6a472017-11-14 14:53:06 -0800355 return super.getBounds();
Chong Zhangb816b862016-01-25 12:01:12 -0800356 }
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700357 }
358
359 // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
360 // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
361 // system.
Bryce Leef3c6a472017-11-14 14:53:06 -0800362 return mDisplayContent.getBounds();
Wale Ogunwalef175e8a2015-09-29 11:07:06 -0700363 }
364
Winson Chung84a38342016-11-08 16:15:10 -0800365 /**
Winson Chung40a5f932017-04-13 16:39:36 -0700366 * Sets the bounds animation target bounds ahead of an animation. This can't currently be done
367 * in onAnimationStart() since that is started on the UiThread.
Winson Chung84a38342016-11-08 16:15:10 -0800368 */
Winson Chung8bca9e42017-04-16 15:59:43 -0700369 void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds, boolean toFullscreen) {
Winson Chung40a5f932017-04-13 16:39:36 -0700370 mBoundsAnimatingRequested = true;
Winson Chung8bca9e42017-04-16 15:59:43 -0700371 mBoundsAnimatingToFullscreen = toFullscreen;
Winson Chung08f81892017-03-02 15:40:51 -0800372 if (destBounds != null) {
373 mBoundsAnimationTarget.set(destBounds);
Winson Chung84a38342016-11-08 16:15:10 -0800374 } else {
375 mBoundsAnimationTarget.setEmpty();
376 }
Winson Chung8bca9e42017-04-16 15:59:43 -0700377 if (sourceHintBounds != null) {
378 mBoundsAnimationSourceHintBounds.set(sourceHintBounds);
379 } else {
380 mBoundsAnimationSourceHintBounds.setEmpty();
381 }
Robert Carr18f622f2017-05-08 11:20:43 -0700382
Bryce Leef3c6a472017-11-14 14:53:06 -0800383 mPreAnimationBounds.set(getRawBounds());
Winson Chung84a38342016-11-08 16:15:10 -0800384 }
385
386 /**
Winson Chung40a5f932017-04-13 16:39:36 -0700387 * @return the final bounds for the bounds animation.
Winson Chung08f81892017-03-02 15:40:51 -0800388 */
Winson Chung40a5f932017-04-13 16:39:36 -0700389 void getFinalAnimationBounds(Rect outBounds) {
390 outBounds.set(mBoundsAnimationTarget);
Winson Chung08f81892017-03-02 15:40:51 -0800391 }
392
393 /**
Winson Chung40a5f932017-04-13 16:39:36 -0700394 * @return the final source bounds for the bounds animation.
Winson Chung84a38342016-11-08 16:15:10 -0800395 */
Winson Chung8bca9e42017-04-16 15:59:43 -0700396 void getFinalAnimationSourceHintBounds(Rect outBounds) {
397 outBounds.set(mBoundsAnimationSourceHintBounds);
Winson Chung40a5f932017-04-13 16:39:36 -0700398 }
399
400 /**
401 * @return the final animation bounds if the task stack is currently being animated, or the
402 * current stack bounds otherwise.
403 */
404 void getAnimationOrCurrentBounds(Rect outBounds) {
405 if ((mBoundsAnimatingRequested || mBoundsAnimating) && !mBoundsAnimationTarget.isEmpty()) {
406 getFinalAnimationBounds(outBounds);
Winson Chung84a38342016-11-08 16:15:10 -0800407 return;
408 }
409 getBounds(outBounds);
410 }
411
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800412 /** Bounds of the stack with other system factors taken into consideration. */
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800413 public void getDimBounds(Rect out) {
414 getBounds(out);
415 }
416
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700417 void updateDisplayInfo(Rect bounds) {
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800418 if (mDisplayContent == null) {
419 return;
420 }
Jorim Jaggi737af722015-12-31 10:42:27 +0100421
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700422 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
423 mChildren.get(taskNdx).updateDisplayInfo(mDisplayContent);
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800424 }
425 if (bounds != null) {
426 setBounds(bounds);
427 return;
Bryce Leef3c6a472017-11-14 14:53:06 -0800428 } else if (matchParentBounds()) {
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800429 setBounds(null);
430 return;
431 }
432
Bryce Leef3c6a472017-11-14 14:53:06 -0800433 mTmpRect2.set(getRawBounds());
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800434 final int newRotation = mDisplayContent.getDisplayInfo().rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700435 final int newDensity = mDisplayContent.getDisplayInfo().logicalDensityDpi;
436 if (mRotation == newRotation && mDensity == newDensity) {
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800437 setBounds(mTmpRect2);
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800438 }
Jorim Jaggieb1cb922016-04-27 20:37:45 -0700439
440 // If the rotation or density didn't match, we'll update it in onConfigurationChanged.
Wale Ogunwale9d3de4c2015-02-01 16:49:44 -0800441 }
442
Andrii Kulian441e4492016-09-29 15:25:00 -0700443 /** @return true if bounds were updated to some non-empty value. */
444 boolean updateBoundsAfterConfigChange() {
Andrii Kulian0be2cfe2016-05-25 14:27:39 -0700445 if (mDisplayContent == null) {
446 // If the stack is already detached we're not updating anything,
447 // as it's going away soon anyway.
448 return false;
449 }
Winson Chung19953ca2017-04-11 11:19:23 -0700450
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700451 if (inPinnedWindowingMode()) {
Winson Chung40a5f932017-04-13 16:39:36 -0700452 getAnimationOrCurrentBounds(mTmpRect2);
Winson Chung19953ca2017-04-11 11:19:23 -0700453 boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
454 mTmpRect2, mTmpRect3);
455 if (updated) {
456 mBoundsAfterRotation.set(mTmpRect3);
457
458 // Once we've set the bounds based on the rotation of the old bounds in the new
459 // orientation, clear the animation target bounds since they are obsolete, and
460 // cancel any currently running animations
461 mBoundsAnimationTarget.setEmpty();
Winson Chung8bca9e42017-04-16 15:59:43 -0700462 mBoundsAnimationSourceHintBounds.setEmpty();
Winson Chung19953ca2017-04-11 11:19:23 -0700463 mCancelCurrentBoundsAnimation = true;
464 return true;
465 }
466 }
467
Jorim Jaggi737af722015-12-31 10:42:27 +0100468 final int newRotation = getDisplayInfo().rotation;
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700469 final int newDensity = getDisplayInfo().logicalDensityDpi;
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800470
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700471 if (mRotation == newRotation && mDensity == newDensity) {
Jorim Jaggieb1cb922016-04-27 20:37:45 -0700472 // Nothing to do here as we already update the state in updateDisplayInfo.
Chong Zhang167bbfac2016-03-31 09:44:34 -0700473 return false;
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -0800474 }
475
Bryce Leef3c6a472017-11-14 14:53:06 -0800476 if (matchParentBounds()) {
Chong Zhangccc335c2016-05-13 11:04:38 -0700477 // Update stack bounds again since rotation changed since updateDisplayInfo().
478 setBounds(null);
479 // Return false since we don't need the client to resize.
480 return false;
481 }
482
Bryce Leef3c6a472017-11-14 14:53:06 -0800483 mTmpRect2.set(getRawBounds());
Jorim Jaggi737af722015-12-31 10:42:27 +0100484 mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700485 if (inSplitScreenPrimaryWindowingMode()) {
Matthew Ngcb1b8e42017-10-20 16:29:23 -0700486 repositionPrimarySplitScreenStackAfterRotation(mTmpRect2);
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700487 snapDockedStackAfterRotation(mTmpRect2);
488 final int newDockSide = getDockSide(mTmpRect2);
Winson Chungcd1ff642016-10-26 09:44:43 -0700489
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700490 // Update the dock create mode and clear the dock create bounds, these
491 // might change after a rotation and the original values will be invalid.
492 mService.setDockedStackCreateStateLocked(
493 (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
Matthew Ngbf155872017-10-27 15:24:39 -0700494 ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
495 : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT,
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700496 null);
497 mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
Jorim Jaggi737af722015-12-31 10:42:27 +0100498 }
499
Jorim Jaggieb1cb922016-04-27 20:37:45 -0700500 mBoundsAfterRotation.set(mTmpRect2);
Chong Zhang167bbfac2016-03-31 09:44:34 -0700501 return true;
502 }
503
Matthew Ngaa2b6202017-02-10 14:48:21 -0800504 void getBoundsForNewConfiguration(Rect outBounds) {
Chong Zhang167bbfac2016-03-31 09:44:34 -0700505 outBounds.set(mBoundsAfterRotation);
506 mBoundsAfterRotation.setEmpty();
Jorim Jaggi737af722015-12-31 10:42:27 +0100507 }
508
509 /**
Matthew Ngcb1b8e42017-10-20 16:29:23 -0700510 * Some primary split screen sides are not allowed by the policy. This method queries the policy
511 * and moves the primary stack around if needed.
Jorim Jaggi5060bd82016-02-19 17:12:19 -0800512 *
Matthew Ngcb1b8e42017-10-20 16:29:23 -0700513 * @param inOutBounds the bounds of the primary stack to adjust
Jorim Jaggi5060bd82016-02-19 17:12:19 -0800514 */
Matthew Ngcb1b8e42017-10-20 16:29:23 -0700515 private void repositionPrimarySplitScreenStackAfterRotation(Rect inOutBounds) {
Jorim Jaggi5060bd82016-02-19 17:12:19 -0800516 int dockSide = getDockSide(inOutBounds);
Matthew Ngcb1b8e42017-10-20 16:29:23 -0700517 if (mDisplayContent.getDockedDividerController().canPrimaryStackDockTo(dockSide)) {
Jorim Jaggi5060bd82016-02-19 17:12:19 -0800518 return;
519 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800520 mDisplayContent.getBounds(mTmpRect);
Jorim Jaggi5060bd82016-02-19 17:12:19 -0800521 dockSide = DockedDividerUtils.invertDockSide(dockSide);
522 switch (dockSide) {
523 case DOCKED_LEFT:
524 int movement = inOutBounds.left;
525 inOutBounds.left -= movement;
526 inOutBounds.right -= movement;
527 break;
528 case DOCKED_RIGHT:
529 movement = mTmpRect.right - inOutBounds.right;
530 inOutBounds.left += movement;
531 inOutBounds.right += movement;
532 break;
533 case DOCKED_TOP:
534 movement = inOutBounds.top;
535 inOutBounds.top -= movement;
536 inOutBounds.bottom -= movement;
537 break;
538 case DOCKED_BOTTOM:
539 movement = mTmpRect.bottom - inOutBounds.bottom;
540 inOutBounds.top += movement;
541 inOutBounds.bottom += movement;
542 break;
543 }
544 }
545
546 /**
Jorim Jaggi737af722015-12-31 10:42:27 +0100547 * Snaps the bounds after rotation to the closest snap target for the docked stack.
548 */
549 private void snapDockedStackAfterRotation(Rect outBounds) {
550
551 // Calculate the current position.
552 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700553 final int dividerSize = mDisplayContent.getDockedDividerController().getContentWidth();
Jorim Jaggi737af722015-12-31 10:42:27 +0100554 final int dockSide = getDockSide(outBounds);
555 final int dividerPosition = DockedDividerUtils.calculatePositionForBounds(outBounds,
556 dockSide, dividerSize);
Adrian Roos11c25582018-02-19 18:06:36 +0100557 final int displayWidth = displayInfo.logicalWidth;
558 final int displayHeight = displayInfo.logicalHeight;
Jorim Jaggi737af722015-12-31 10:42:27 +0100559
560 // Snap the position to a target.
561 final int rotation = displayInfo.rotation;
Andrii Kulian441e4492016-09-29 15:25:00 -0700562 final int orientation = mDisplayContent.getConfiguration().orientation;
Adrian Roos11c25582018-02-19 18:06:36 +0100563 mService.mPolicy.getStableInsetsLw(rotation, displayWidth, displayHeight,
564 displayInfo.displayCutout, outBounds);
Jorim Jaggi737af722015-12-31 10:42:27 +0100565 final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
Jorim Jaggidf012d52016-01-15 22:40:13 -0800566 mService.mContext.getResources(), displayWidth, displayHeight,
Matthew Nge15352e2016-12-20 15:36:29 -0800567 dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
Matthew Ngf59a4132017-10-25 12:03:22 -0700568 getDockSide(), isMinimizedDockAndHomeStackResizable());
Jorim Jaggi737af722015-12-31 10:42:27 +0100569 final SnapTarget target = algorithm.calculateNonDismissingSnapTarget(dividerPosition);
570
571 // Recalculate the bounds based on the position of the target.
572 DockedDividerUtils.calculateBoundsForPosition(target.position, dockSide,
573 outBounds, displayInfo.logicalWidth, displayInfo.logicalHeight,
574 dividerSize);
575 }
576
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700577 // 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 -0800578 void addTask(Task task, int position) {
579 addTask(task, position, task.showForAllUsers(), true /* moveParents */);
Wale Ogunwale3fcb4a82015-04-06 14:00:13 -0700580 }
581
Craig Mautner00af9fe2013-03-25 09:13:41 -0700582 /**
Andrii Kuliand2765632016-12-12 22:26:34 -0800583 * Put a Task in this stack. Used for adding only.
584 * When task is added to top of the stack, the entire branch of the hierarchy (including stack
585 * and display) will be brought to top.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700586 * @param task The task to add.
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800587 * @param position Target position to add the task to.
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700588 * @param showForAllUsers Whether to show the task regardless of the current user.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700589 */
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800590 void addTask(Task task, int position, boolean showForAllUsers, boolean moveParents) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800591 final TaskStack currentStack = task.mStack;
592 // TODO: We pass stack to task's constructor, but we still need to call this method.
593 // This doesn't make sense, mStack will already be set equal to "this" at this point.
594 if (currentStack != null && currentStack.mStackId != mStackId) {
595 throw new IllegalStateException("Trying to add taskId=" + task.mTaskId
596 + " to stackId=" + mStackId
597 + ", but it is already attached to stackId=" + task.mStack.mStackId);
598 }
599
Andrii Kuliand2765632016-12-12 22:26:34 -0800600 // Add child task.
601 task.mStack = this;
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800602 addChild(task, null);
Andrii Kuliand2765632016-12-12 22:26:34 -0800603
604 // Move child to a proper position, as some restriction for position might apply.
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800605 positionChildAt(position, task, moveParents /* includingParents */, showForAllUsers);
Andrii Kuliand2765632016-12-12 22:26:34 -0800606 }
607
608 @Override
609 void positionChildAt(int position, Task child, boolean includingParents) {
610 positionChildAt(position, child, includingParents, child.showForAllUsers());
611 }
612
613 /**
614 * Overridden version of {@link TaskStack#positionChildAt(int, Task, boolean)}. Used in
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800615 * {@link TaskStack#addTask(Task, int, boolean showForAllUsers, boolean)}, as it can receive
Andrii Kuliand2765632016-12-12 22:26:34 -0800616 * showForAllUsers param from {@link AppWindowToken} instead of {@link Task#showForAllUsers()}.
617 */
618 private void positionChildAt(int position, Task child, boolean includingParents,
619 boolean showForAllUsers) {
620 final int targetPosition = findPositionForTask(child, position, showForAllUsers,
621 false /* addingNew */);
622 super.positionChildAt(targetPosition, child, includingParents);
623
624 // Log positioning.
625 if (DEBUG_TASK_MOVEMENT)
626 Slog.d(TAG_WM, "positionTask: task=" + this + " position=" + position);
627
628 final int toTop = targetPosition == mChildren.size() - 1 ? 1 : 0;
629 EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, child.mTaskId, toTop, targetPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700630 }
631
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700632 // 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 -0800633 // have to do complicated things like we are doing in this method.
634 private int findPositionForTask(Task task, int targetPosition, boolean showForAllUsers,
635 boolean addingNew) {
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700636 final boolean canShowTask =
637 showForAllUsers || mService.isCurrentProfileLocked(task.mUserId);
Andrii Kuliand2765632016-12-12 22:26:34 -0800638
639 final int stackSize = mChildren.size();
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700640 int minPosition = 0;
Andrii Kuliand2765632016-12-12 22:26:34 -0800641 int maxPosition = addingNew ? stackSize : stackSize - 1;
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700642
643 if (canShowTask) {
644 minPosition = computeMinPosition(minPosition, stackSize);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700645 } else {
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700646 maxPosition = computeMaxPosition(maxPosition);
Craig Mautnerac6f8432013-07-17 13:24:59 -0700647 }
Evan Rosky9c448172017-11-02 14:19:27 -0700648
649 // preserve POSITION_BOTTOM/POSITION_TOP positions if they are still valid.
650 if (targetPosition == POSITION_BOTTOM && minPosition == 0) {
651 return POSITION_BOTTOM;
652 } else if (targetPosition == POSITION_TOP
653 && maxPosition == (addingNew ? stackSize : stackSize - 1)) {
654 return POSITION_TOP;
655 }
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700656 // Reset position based on minimum/maximum possible positions.
Andrii Kuliand2765632016-12-12 22:26:34 -0800657 return Math.min(Math.max(targetPosition, minPosition), maxPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700658 }
659
660 /** Calculate the minimum possible position for a task that can be shown to the user.
661 * The minimum position will be above all other tasks that can't be shown.
662 * @param minPosition The minimum position the caller is suggesting.
663 * We will start adjusting up from here.
664 * @param size The size of the current task list.
665 */
666 private int computeMinPosition(int minPosition, int size) {
667 while (minPosition < size) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700668 final Task tmpTask = mChildren.get(minPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700669 final boolean canShowTmpTask =
670 tmpTask.showForAllUsers()
671 || mService.isCurrentProfileLocked(tmpTask.mUserId);
672 if (canShowTmpTask) {
673 break;
674 }
675 minPosition++;
676 }
677 return minPosition;
678 }
679
680 /** Calculate the maximum possible position for a task that can't be shown to the user.
681 * The maximum position will be below all other tasks that can be shown.
682 * @param maxPosition The maximum position the caller is suggesting.
683 * We will start adjusting down from here.
684 */
685 private int computeMaxPosition(int maxPosition) {
686 while (maxPosition > 0) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800687 final Task tmpTask = mChildren.get(maxPosition);
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700688 final boolean canShowTmpTask =
689 tmpTask.showForAllUsers()
690 || mService.isCurrentProfileLocked(tmpTask.mUserId);
691 if (!canShowTmpTask) {
692 break;
693 }
694 maxPosition--;
695 }
696 return maxPosition;
Craig Mautnerc00204b2013-03-05 15:02:14 -0800697 }
698
Craig Mautner00af9fe2013-03-25 09:13:41 -0700699 /**
Craig Mautner04a0ea62014-01-13 12:51:26 -0800700 * Delete a Task from this stack. If it is the last Task in the stack, move this stack to the
701 * back.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700702 * @param task The Task to delete.
Craig Mautner00af9fe2013-03-25 09:13:41 -0700703 */
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700704 @Override
705 void removeChild(Task task) {
706 if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "removeChild: task=" + task);
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700707
708 super.removeChild(task);
Andrii Kuliand2765632016-12-12 22:26:34 -0800709 task.mStack = null;
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700710
Craig Mautnerdf88d732014-01-27 09:21:32 -0800711 if (mDisplayContent != null) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -0700712 if (mChildren.isEmpty()) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800713 getParent().positionChildAt(POSITION_BOTTOM, this, false /* includingParents */);
Craig Mautnerdf88d732014-01-27 09:21:32 -0800714 }
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700715 mDisplayContent.setLayoutNeeded();
Craig Mautner04a0ea62014-01-13 12:51:26 -0800716 }
Craig Mautnere3119b72015-01-20 15:02:36 -0800717 for (int appNdx = mExitingAppTokens.size() - 1; appNdx >= 0; --appNdx) {
718 final AppWindowToken wtoken = mExitingAppTokens.get(appNdx);
Bryce Lee6d410262017-02-28 15:30:17 -0800719 if (wtoken.getTask() == task) {
Craig Mautnere3119b72015-01-20 15:02:36 -0800720 wtoken.mIsExiting = false;
721 mExitingAppTokens.remove(appNdx);
722 }
723 }
Craig Mautnerc00204b2013-03-05 15:02:14 -0800724 }
725
Wale Ogunwale61911492017-10-11 08:50:50 -0700726 @Override
727 public void onConfigurationChanged(Configuration newParentConfig) {
728 final int prevWindowingMode = getWindowingMode();
Jorim Jaggi1a6d98b2018-01-08 16:23:00 +0100729 super.onConfigurationChanged(newParentConfig);
730
chaviwe07246a2017-12-12 16:18:29 -0800731 // Only need to update surface size here since the super method will handle updating
732 // surface position.
733 updateSurfaceSize(getPendingTransaction());
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800734 final int windowingMode = getWindowingMode();
chaviwe07246a2017-12-12 16:18:29 -0800735
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800736 if (mDisplayContent == null || prevWindowingMode == windowingMode) {
737 return;
Wale Ogunwale61911492017-10-11 08:50:50 -0700738 }
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800739 mDisplayContent.onStackWindowingModeChanged(this);
740 updateBoundsForWindowModeChange();
Wale Ogunwale61911492017-10-11 08:50:50 -0700741 }
742
chaviwe07246a2017-12-12 16:18:29 -0800743 private void updateSurfaceBounds() {
chaviw2f0567b2018-01-29 16:22:02 -0800744 updateSurfaceSize(getPendingTransaction());
745 updateSurfacePosition();
chaviwe07246a2017-12-12 16:18:29 -0800746 scheduleAnimation();
747 }
748
Robert Carr32bcb102018-01-29 15:03:23 -0800749 /**
750 * Calculate an amount by which to expand the stack bounds in each direction.
751 * Used to make room for shadows in the pinned windowing mode.
752 */
753 int getStackOutset() {
Evan Roskyb1ea7ca2018-04-05 17:17:35 -0700754 DisplayContent displayContent = getDisplayContent();
755 if (inPinnedWindowingMode() && displayContent != null) {
756 final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
Robert Carr74a66a22018-02-23 12:17:51 -0800757
758 // We multiply by two to match the client logic for converting view elevation
759 // to insets, as in {@link WindowManager.LayoutParams#setSurfaceInsets}
760 return (int)Math.ceil(mService.dipToPixel(PINNED_WINDOWING_MODE_ELEVATION_IN_DIP,
761 displayMetrics) * 2);
Robert Carr32bcb102018-01-29 15:03:23 -0800762 }
763 return 0;
764 }
765
chaviwe07246a2017-12-12 16:18:29 -0800766 private void updateSurfaceSize(SurfaceControl.Transaction transaction) {
767 if (mSurfaceControl == null) {
768 return;
769 }
770
771 final Rect stackBounds = getBounds();
Robert Carr32bcb102018-01-29 15:03:23 -0800772 int width = stackBounds.width();
773 int height = stackBounds.height();
774
775 final int outset = getStackOutset();
776 width += 2*outset;
777 height += 2*outset;
778
chaviw3e751af2018-01-11 11:22:39 -0800779 if (width == mLastSurfaceSize.x && height == mLastSurfaceSize.y) {
780 return;
781 }
782 transaction.setSize(mSurfaceControl, width, height);
783 mLastSurfaceSize.set(width, height);
chaviwe07246a2017-12-12 16:18:29 -0800784 }
785
Wale Ogunwale61911492017-10-11 08:50:50 -0700786 @Override
Wale Ogunwale02319a62016-09-26 15:21:22 -0700787 void onDisplayChanged(DisplayContent dc) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800788 if (mDisplayContent != null) {
Wale Ogunwale02319a62016-09-26 15:21:22 -0700789 throw new IllegalStateException("onDisplayChanged: Already attached");
Craig Mautner4a1cb222013-12-04 16:14:06 -0800790 }
Craig Mautnerdf88d732014-01-27 09:21:32 -0800791
Wale Ogunwale02319a62016-09-26 15:21:22 -0700792 mDisplayContent = dc;
Robert Carrf59b8dd2017-10-02 18:58:36 -0700793
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800794 updateBoundsForWindowModeChange();
Robert Carrf59b8dd2017-10-02 18:58:36 -0700795 mAnimationBackgroundSurface = makeChildSurface(null).setColorLayer(true)
796 .setName("animation background stackId=" + mStackId)
797 .build();
798
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800799 super.onDisplayChanged(dc);
800 }
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700801
Wale Ogunwale30e441d2017-11-09 08:28:45 -0800802 private void updateBoundsForWindowModeChange() {
Winson Chung985f54d2018-05-01 18:17:19 -0700803 final Rect bounds = calculateBoundsForWindowModeChange();
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700804
chaviwbe43ac82018-04-04 15:14:49 -0700805 if (inSplitScreenSecondaryWindowingMode()) {
806 // When the stack is resized due to entering split screen secondary, offset the
807 // windows to compensate for the new stack position.
808 forAllWindows(w -> {
809 w.mWinAnimator.setOffsetPositionForStackResize(true);
810 }, true);
811 }
812
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700813 updateDisplayInfo(bounds);
Robert Carr74a66a22018-02-23 12:17:51 -0800814 updateSurfaceBounds();
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700815 }
816
Winson Chung985f54d2018-05-01 18:17:19 -0700817 private Rect calculateBoundsForWindowModeChange() {
818 final boolean inSplitScreenPrimary = inSplitScreenPrimaryWindowingMode();
819 final TaskStack splitScreenStack =
820 mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
821 if (inSplitScreenPrimary || (splitScreenStack != null
822 && inSplitScreenSecondaryWindowingMode() && !splitScreenStack.fillsParent())) {
823 // The existence of a docked stack affects the size of other static stack created since
824 // the docked stack occupies a dedicated region on screen, but only if the dock stack is
825 // not fullscreen. If it's fullscreen, it means that we are in the transition of
826 // dismissing it, so we must not resize this stack.
827 final Rect bounds = new Rect();
828 mDisplayContent.getBounds(mTmpRect);
829 mTmpRect2.setEmpty();
830 if (splitScreenStack != null) {
831 if (inSplitScreenSecondaryWindowingMode()
832 && mDisplayContent.mDividerControllerLocked.isMinimizedDock()
833 && splitScreenStack.getTopChild() != null) {
834 // If the primary split screen stack is currently minimized, then don't use the
835 // stack bounds of the minimized stack, instead, use the temporary task bounds
836 // to calculate the appropriate uniminized size of any secondary split stack
837 // TODO: Find a cleaner way for computing new stack bounds while minimized that
838 // doesn't assume the primary stack's task bounds as the temp task bounds
839 splitScreenStack.getTopChild().getBounds(mTmpRect2);
840 } else {
841 splitScreenStack.getRawBounds(mTmpRect2);
842 }
843 }
844 final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
845 == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
846 getStackDockedModeBounds(mTmpRect, bounds, mTmpRect2,
847 mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
848 return bounds;
849 } else if (inPinnedWindowingMode()) {
850 // Update the bounds based on any changes to the display info
851 getAnimationOrCurrentBounds(mTmpRect2);
852 if (mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
853 mTmpRect2, mTmpRect3)) {
854 return new Rect(mTmpRect3);
855 }
856 }
857 return null;
858 }
859
Matthew Ngaa2b6202017-02-10 14:48:21 -0800860 /**
861 * Determines the stack and task bounds of the other stack when in docked mode. The current task
862 * bounds is passed in but depending on the stack, the task and stack must match. Only in
863 * minimized mode with resizable launcher, the other stack ignores calculating the stack bounds
864 * and uses the task bounds passed in as the stack and task bounds, otherwise the stack bounds
865 * is calculated and is also used for its task bounds.
866 * If any of the out bounds are empty, it represents default bounds
867 *
868 * @param currentTempTaskBounds the current task bounds of the other stack
869 * @param outStackBounds the calculated stack bounds of the other stack
870 * @param outTempTaskBounds the calculated task bounds of the other stack
871 * @param ignoreVisibility ignore visibility in getting the stack bounds
872 */
873 void getStackDockedModeBoundsLocked(Rect currentTempTaskBounds, Rect outStackBounds,
874 Rect outTempTaskBounds, boolean ignoreVisibility) {
875 outTempTaskBounds.setEmpty();
876
877 // When the home stack is resizable, should always have the same stack and task bounds
Wale Ogunwale68278562017-09-23 17:13:55 -0700878 if (isActivityTypeHome()) {
Winson Chungf7fb5e32017-05-23 17:47:05 -0700879 final Task homeTask = findHomeTask();
880 if (homeTask != null && homeTask.isResizeable()) {
Wale Ogunwale649c1602017-04-24 10:15:31 -0700881 // Calculate the home stack bounds when in docked mode and the home stack is
882 // resizeable.
883 getDisplayContent().mDividerControllerLocked
884 .getHomeStackBoundsInDockedMode(outStackBounds);
885 } else {
886 // Home stack isn't resizeable, so don't specify stack bounds.
887 outStackBounds.setEmpty();
888 }
889
Matthew Ngaa2b6202017-02-10 14:48:21 -0800890 outTempTaskBounds.set(outStackBounds);
891 return;
892 }
893
894 // When minimized state, the stack bounds for all non-home and docked stack bounds should
895 // match the passed task bounds
896 if (isMinimizedDockAndHomeStackResizable() && currentTempTaskBounds != null) {
897 outStackBounds.set(currentTempTaskBounds);
898 return;
Matthew Nge15352e2016-12-20 15:36:29 -0800899 }
900
Wale Ogunwale926aade2017-08-29 11:24:37 -0700901 if (!inSplitScreenWindowingMode() || mDisplayContent == null) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800902 outStackBounds.set(getRawBounds());
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700903 return;
904 }
905
Wale Ogunwale61911492017-10-11 08:50:50 -0700906 final TaskStack dockedStack =
Matthew Ng64e77cf2017-10-31 14:01:31 -0700907 mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700908 if (dockedStack == null) {
909 // Not sure why you are calling this method when there is no docked stack...
910 throw new IllegalStateException(
911 "Calling getStackDockedModeBoundsLocked() when there is no docked stack.");
912 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700913 if (!ignoreVisibility && !dockedStack.isVisible()) {
Filip Gruszczynski54977fe2015-10-19 17:26:45 -0700914 // The docked stack is being dismissed, but we caught before it finished being
915 // dismissed. In that case we want to treat it as if it is not occupying any space and
916 // let others occupy the whole display.
Bryce Leef3c6a472017-11-14 14:53:06 -0800917 mDisplayContent.getBounds(outStackBounds);
Filip Gruszczynski54977fe2015-10-19 17:26:45 -0700918 return;
919 }
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700920
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700921 final int dockedSide = dockedStack.getDockSide();
922 if (dockedSide == DOCKED_INVALID) {
923 // Not sure how you got here...Only thing we can do is return current bounds.
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800924 Slog.e(TAG_WM, "Failed to get valid docked side for docked stack=" + dockedStack);
Bryce Leef3c6a472017-11-14 14:53:06 -0800925 outStackBounds.set(getRawBounds());
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700926 return;
927 }
928
Bryce Leef3c6a472017-11-14 14:53:06 -0800929 mDisplayContent.getBounds(mTmpRect);
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700930 dockedStack.getRawBounds(mTmpRect2);
Wale Ogunwalea9f9b372016-02-04 18:04:39 -0800931 final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700932 getStackDockedModeBounds(mTmpRect, outStackBounds, mTmpRect2,
Jorim Jaggi1fcbab62015-11-04 16:39:50 +0100933 mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700934
935 }
936
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700937 /**
Wale Ogunwaleffc11bb2015-10-10 13:05:45 -0700938 * Outputs the bounds a stack should be given the presence of a docked stack on the display.
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700939 * @param displayRect The bounds of the display the docked stack is on.
940 * @param outBounds Output bounds that should be used for the stack.
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700941 * @param dockedBounds Bounds of the docked stack.
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700942 * @param dockDividerWidth We need to know the width of the divider make to the output bounds
943 * close to the side of the dock.
944 * @param dockOnTopOrLeft If the docked stack is on the top or left side of the screen.
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700945 */
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -0800946 private void getStackDockedModeBounds(
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700947 Rect displayRect, Rect outBounds, Rect dockedBounds, int dockDividerWidth,
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700948 boolean dockOnTopOrLeft) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700949 final boolean dockedStack = inSplitScreenPrimaryWindowingMode();
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700950 final boolean splitHorizontally = displayRect.width() > displayRect.height();
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700951
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700952 outBounds.set(displayRect);
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700953 if (dockedStack) {
Jorim Jaggi9ea2f7b2015-11-23 18:08:28 -0800954 if (mService.mDockedStackCreateBounds != null) {
955 outBounds.set(mService.mDockedStackCreateBounds);
956 return;
957 }
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100958
959 // The initial bounds of the docked stack when it is created about half the screen space
960 // and its bounds can be adjusted after that. The bounds of all other stacks are
961 // adjusted to occupy whatever screen space the docked stack isn't occupying.
962 final DisplayInfo di = mDisplayContent.getDisplayInfo();
963 mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
Adrian Roos11c25582018-02-19 18:06:36 +0100964 di.displayCutout, mTmpRect2);
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100965 final int position = new DividerSnapAlgorithm(mService.mContext.getResources(),
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100966 di.logicalWidth,
967 di.logicalHeight,
968 dockDividerWidth,
Andrii Kulian441e4492016-09-29 15:25:00 -0700969 mDisplayContent.getConfiguration().orientation == ORIENTATION_PORTRAIT,
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100970 mTmpRect2).getMiddleTarget().position;
971
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700972 if (dockOnTopOrLeft) {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700973 if (splitHorizontally) {
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100974 outBounds.right = position;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700975 } else {
Jorim Jaggid434dcb2016-01-06 17:18:44 +0100976 outBounds.bottom = position;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700977 }
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700978 } else {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700979 if (splitHorizontally) {
Andrii Kulianef3b2722016-04-08 12:45:27 -0700980 outBounds.left = position + dockDividerWidth;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700981 } else {
Andrii Kulianef3b2722016-04-08 12:45:27 -0700982 outBounds.top = position + dockDividerWidth;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700983 }
984 }
985 return;
986 }
987
988 // Other stacks occupy whatever space is left by the docked stack.
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700989 if (!dockOnTopOrLeft) {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700990 if (splitHorizontally) {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700991 outBounds.right = dockedBounds.left - dockDividerWidth;
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700992 } else {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700993 outBounds.bottom = dockedBounds.top - dockDividerWidth;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700994 }
995 } else {
996 if (splitHorizontally) {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700997 outBounds.left = dockedBounds.right + dockDividerWidth;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -0700998 } else {
Filip Gruszczynskiba47f812015-10-28 16:11:55 -0700999 outBounds.top = dockedBounds.bottom + dockDividerWidth;
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001000 }
1001 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001002 DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
Wale Ogunwaleb34a7ad2015-08-14 11:05:30 -07001003 }
1004
Wale Ogunwalea9f9b372016-02-04 18:04:39 -08001005 void resetDockedStackToMiddle() {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001006 if (inSplitScreenPrimaryWindowingMode()) {
Wale Ogunwalea9f9b372016-02-04 18:04:39 -08001007 throw new IllegalStateException("Not a docked stack=" + this);
1008 }
1009
1010 mService.mDockedStackCreateBounds = null;
1011
1012 final Rect bounds = new Rect();
Matthew Nge15352e2016-12-20 15:36:29 -08001013 final Rect tempBounds = new Rect();
Matthew Ngaa2b6202017-02-10 14:48:21 -08001014 getStackDockedModeBoundsLocked(null /* currentTempTaskBounds */, bounds, tempBounds,
1015 true /*ignoreVisibility*/);
Wale Ogunwale1666e312016-12-16 11:27:18 -08001016 getController().requestResize(bounds);
1017 }
1018
1019 @Override
1020 StackWindowController getController() {
1021 return (StackWindowController) super.getController();
Wale Ogunwalea9f9b372016-02-04 18:04:39 -08001022 }
1023
Wale Ogunwale10124582016-09-15 20:25:50 -07001024 @Override
1025 void removeIfPossible() {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001026 if (isSelfOrChildAnimating()) {
Wale Ogunwale10124582016-09-15 20:25:50 -07001027 mDeferRemoval = true;
1028 return;
1029 }
1030 removeImmediately();
1031 }
1032
1033 @Override
Wale Ogunwale61911492017-10-11 08:50:50 -07001034 void onParentSet() {
Robert Carrb1579c82017-09-05 14:54:47 -07001035 super.onParentSet();
1036
Wale Ogunwale61911492017-10-11 08:50:50 -07001037 if (getParent() != null || mDisplayContent == null) {
1038 return;
1039 }
Wale Ogunwale10124582016-09-15 20:25:50 -07001040
Craig Mautnerdf88d732014-01-27 09:21:32 -08001041 EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
Wale Ogunwale10124582016-09-15 20:25:50 -07001042
1043 if (mAnimationBackgroundSurface != null) {
Robert Carrf59b8dd2017-10-02 18:58:36 -07001044 mAnimationBackgroundSurface.destroy();
Wale Ogunwale10124582016-09-15 20:25:50 -07001045 mAnimationBackgroundSurface = null;
1046 }
Wale Ogunwale10124582016-09-15 20:25:50 -07001047
Andrii Kulian839def92016-11-02 10:58:58 -07001048 mDisplayContent = null;
1049 mService.mWindowPlacerLocked.requestTraversal();
Craig Mautner00af9fe2013-03-25 09:13:41 -07001050 }
1051
Craig Mautner05d29032013-05-03 13:40:13 -07001052 void resetAnimationBackgroundAnimator() {
1053 mAnimationBackgroundAnimator = null;
Robert Carrf59b8dd2017-10-02 18:58:36 -07001054 hideAnimationSurface();
Craig Mautner05d29032013-05-03 13:40:13 -07001055 }
1056
Craig Mautner05d29032013-05-03 13:40:13 -07001057 void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
1058 int animLayer = winAnimator.mAnimLayer;
1059 if (mAnimationBackgroundAnimator == null
1060 || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
1061 mAnimationBackgroundAnimator = winAnimator;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001062 animLayer = mDisplayContent.getLayerForAnimationBackground(winAnimator);
Robert Carrf59b8dd2017-10-02 18:58:36 -07001063 showAnimationSurface(((color >> 24) & 0xff) / 255f);
Craig Mautner05d29032013-05-03 13:40:13 -07001064 }
1065 }
1066
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001067 // TODO: Should each user have there own stacks?
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001068 @Override
Wale Ogunwale498e8c92015-02-13 09:42:46 -08001069 void switchUser() {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001070 super.switchUser();
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001071 int top = mChildren.size();
Craig Mautnerac6f8432013-07-17 13:24:59 -07001072 for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001073 Task task = mChildren.get(taskNdx);
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -07001074 if (mService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001075 mChildren.remove(taskNdx);
1076 mChildren.add(task);
Craig Mautnerac6f8432013-07-17 13:24:59 -07001077 --top;
1078 }
1079 }
1080 }
1081
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001082 /**
1083 * Adjusts the stack bounds if the IME is visible.
1084 *
1085 * @param imeWin The IME window.
1086 */
Keisuke Kuroyanagi19d9a8f2016-05-12 16:49:02 -07001087 void setAdjustedForIme(WindowState imeWin, boolean forceUpdate) {
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001088 mImeWin = imeWin;
Chong Zhangbaba7832016-03-24 10:21:26 -07001089 mImeGoingAway = false;
Keisuke Kuroyanagi19d9a8f2016-05-12 16:49:02 -07001090 if (!mAdjustedForIme || forceUpdate) {
Jorim Jaggiff71d202016-04-14 13:12:36 -07001091 mAdjustedForIme = true;
1092 mAdjustImeAmount = 0f;
Chong Zhangf347ab52016-04-18 21:02:01 -07001093 mAdjustDividerAmount = 0f;
1094 updateAdjustForIme(0f, 0f, true /* force */);
Jorim Jaggiff71d202016-04-14 13:12:36 -07001095 }
Chong Zhangbaba7832016-03-24 10:21:26 -07001096 }
1097
1098 boolean isAdjustedForIme() {
Chong Zhang5117e272016-05-03 12:47:34 -07001099 return mAdjustedForIme;
Chong Zhangbaba7832016-03-24 10:21:26 -07001100 }
Chong Zhangbaba7832016-03-24 10:21:26 -07001101
1102 boolean isAnimatingForIme() {
1103 return mImeWin != null && mImeWin.isAnimatingLw();
1104 }
1105
1106 /**
1107 * Update the stack's bounds (crop or position) according to the IME window's
1108 * current position. When IME window is animated, the bottom stack is animated
1109 * together to track the IME window's current position, and the top stack is
1110 * cropped as necessary.
1111 *
1112 * @return true if a traversal should be performed after the adjustment.
1113 */
Chong Zhangf347ab52016-04-18 21:02:01 -07001114 boolean updateAdjustForIme(float adjustAmount, float adjustDividerAmount, boolean force) {
1115 if (adjustAmount != mAdjustImeAmount
1116 || adjustDividerAmount != mAdjustDividerAmount || force) {
Jorim Jaggieb88d832016-04-13 20:17:43 -07001117 mAdjustImeAmount = adjustAmount;
Chong Zhangf347ab52016-04-18 21:02:01 -07001118 mAdjustDividerAmount = adjustDividerAmount;
Jorim Jaggieb88d832016-04-13 20:17:43 -07001119 updateAdjustedBounds();
Jorim Jaggife762342016-10-13 14:33:27 +02001120 return isVisible();
Jorim Jaggieb88d832016-04-13 20:17:43 -07001121 } else {
1122 return false;
Chong Zhangb58bbcc2016-03-23 11:57:36 -07001123 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001124 }
1125
1126 /**
1127 * Resets the adjustment after it got adjusted for the IME.
Chong Zhangbaba7832016-03-24 10:21:26 -07001128 * @param adjustBoundsNow if true, reset and update the bounds immediately and forget about
1129 * animations; otherwise, set flag and animates the window away together
1130 * with IME window.
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001131 */
Chong Zhangbaba7832016-03-24 10:21:26 -07001132 void resetAdjustedForIme(boolean adjustBoundsNow) {
1133 if (adjustBoundsNow) {
1134 mImeWin = null;
Chong Zhangbaba7832016-03-24 10:21:26 -07001135 mImeGoingAway = false;
Jorim Jaggieb88d832016-04-13 20:17:43 -07001136 mAdjustImeAmount = 0f;
Chong Zhangf347ab52016-04-18 21:02:01 -07001137 mAdjustDividerAmount = 0f;
Jorim Jaggif93ac2b2017-10-25 15:20:24 +02001138 if (!mAdjustedForIme) {
1139 return;
1140 }
1141 mAdjustedForIme = false;
Chong Zhangbaba7832016-03-24 10:21:26 -07001142 updateAdjustedBounds();
Wale Ogunwale68278562017-09-23 17:13:55 -07001143 mService.setResizeDimLayer(false, getWindowingMode(), 1.0f);
Chong Zhangbaba7832016-03-24 10:21:26 -07001144 } else {
1145 mImeGoingAway |= mAdjustedForIme;
Chong Zhangb58bbcc2016-03-23 11:57:36 -07001146 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001147 }
1148
1149 /**
1150 * Sets the amount how much we currently minimize our stack.
1151 *
1152 * @param minimizeAmount The amount, between 0 and 1.
1153 * @return Whether the amount has changed and a layout is needed.
1154 */
1155 boolean setAdjustedForMinimizedDock(float minimizeAmount) {
1156 if (minimizeAmount != mMinimizeAmount) {
1157 mMinimizeAmount = minimizeAmount;
1158 updateAdjustedBounds();
Jorim Jaggife762342016-10-13 14:33:27 +02001159 return isVisible();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001160 } else {
1161 return false;
1162 }
1163 }
1164
Matthew Nge15352e2016-12-20 15:36:29 -08001165 boolean shouldIgnoreInput() {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001166 return isAdjustedForMinimizedDockedStack() ||
1167 (inSplitScreenPrimaryWindowingMode() && isMinimizedDockAndHomeStackResizable());
Jorim Jaggi409635b2016-04-01 15:32:28 -07001168 }
1169
Jorim Jaggiff71d202016-04-14 13:12:36 -07001170 /**
1171 * Puts all visible tasks that are adjusted for IME into resizing mode and adds the windows
1172 * to the list of to be drawn windows the service is waiting for.
1173 */
1174 void beginImeAdjustAnimation() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001175 for (int j = mChildren.size() - 1; j >= 0; j--) {
1176 final Task task = mChildren.get(j);
Wale Ogunwale44f21802016-09-02 12:49:48 -07001177 if (task.hasContentToDisplay()) {
Jorim Jaggiff71d202016-04-14 13:12:36 -07001178 task.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001179 task.setWaitingForDrawnIfResizingChanged();
Jorim Jaggiff71d202016-04-14 13:12:36 -07001180 }
1181 }
1182 }
1183
1184 /**
1185 * Resets the resizing state of all windows.
1186 */
1187 void endImeAdjustAnimation() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001188 for (int j = mChildren.size() - 1; j >= 0; j--) {
1189 mChildren.get(j).setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
Jorim Jaggiff71d202016-04-14 13:12:36 -07001190 }
1191 }
1192
Chong Zhang198afac2016-04-15 12:03:11 -07001193 int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
1194 return displayContentRect.top + (int)
1195 ((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN);
1196 }
1197
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001198 private boolean adjustForIME(final WindowState imeWin) {
1199 final int dockedSide = getDockSide();
1200 final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001201 if (imeWin == null || !dockedTopOrBottom) {
1202 return false;
1203 }
1204
Wale Ogunwaledb506192017-12-08 10:57:32 -08001205 final Rect displayStableRect = mTmpRect;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001206 final Rect contentBounds = mTmpRect2;
1207
1208 // Calculate the content bounds excluding the area occupied by IME
Wale Ogunwaledb506192017-12-08 10:57:32 -08001209 getDisplayContent().getStableRect(displayStableRect);
1210 contentBounds.set(displayStableRect);
Jorim Jaggi5ac2ba22016-04-11 21:14:12 -07001211 int imeTop = Math.max(imeWin.getFrameLw().top, contentBounds.top);
Chong Zhangbaba7832016-03-24 10:21:26 -07001212
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001213 imeTop += imeWin.getGivenContentInsetsLw().top;
1214 if (contentBounds.bottom > imeTop) {
1215 contentBounds.bottom = imeTop;
1216 }
1217
Wale Ogunwaledb506192017-12-08 10:57:32 -08001218 final int yOffset = displayStableRect.bottom - contentBounds.bottom;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001219
Chong Zhang198afac2016-04-15 12:03:11 -07001220 final int dividerWidth =
1221 getDisplayContent().mDividerControllerLocked.getContentWidth();
1222 final int dividerWidthInactive =
1223 getDisplayContent().mDividerControllerLocked.getContentWidthInactive();
1224
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001225 if (dockedSide == DOCKED_TOP) {
1226 // If this stack is docked on top, we make it smaller so the bottom stack is not
Chong Zhang198afac2016-04-15 12:03:11 -07001227 // occluded by IME. We shift its bottom up by the height of the IME, but
1228 // leaves at least 30% of the top stack visible.
1229 final int minTopStackBottom =
Wale Ogunwaledb506192017-12-08 10:57:32 -08001230 getMinTopStackBottom(displayStableRect, getRawBounds().bottom);
Chong Zhang198afac2016-04-15 12:03:11 -07001231 final int bottom = Math.max(
Bryce Leef3c6a472017-11-14 14:53:06 -08001232 getRawBounds().bottom - yOffset + dividerWidth - dividerWidthInactive,
Chong Zhang198afac2016-04-15 12:03:11 -07001233 minTopStackBottom);
Bryce Leef3c6a472017-11-14 14:53:06 -08001234 mTmpAdjustedBounds.set(getRawBounds());
1235 mTmpAdjustedBounds.bottom = (int) (mAdjustImeAmount * bottom + (1 - mAdjustImeAmount)
1236 * getRawBounds().bottom);
1237 mFullyAdjustedImeBounds.set(getRawBounds());
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001238 } else {
Chong Zhangf347ab52016-04-18 21:02:01 -07001239 // When the stack is on bottom and has no focus, it's only adjusted for divider width.
1240 final int dividerWidthDelta = dividerWidthInactive - dividerWidth;
1241
1242 // When the stack is on bottom and has focus, it needs to be moved up so as to
1243 // not occluded by IME, and at the same time adjusted for divider width.
1244 // We try to move it up by the height of the IME window, but only to the extent
1245 // that leaves at least 30% of the top stack visible.
1246 // 'top' is where the top of bottom stack will move to in this case.
Bryce Leef3c6a472017-11-14 14:53:06 -08001247 final int topBeforeImeAdjust =
1248 getRawBounds().top - dividerWidth + dividerWidthInactive;
Chong Zhangf347ab52016-04-18 21:02:01 -07001249 final int minTopStackBottom =
Wale Ogunwaledb506192017-12-08 10:57:32 -08001250 getMinTopStackBottom(displayStableRect,
Bryce Leef3c6a472017-11-14 14:53:06 -08001251 getRawBounds().top - dividerWidth);
Chong Zhangf347ab52016-04-18 21:02:01 -07001252 final int top = Math.max(
Bryce Leef3c6a472017-11-14 14:53:06 -08001253 getRawBounds().top - yOffset, minTopStackBottom + dividerWidthInactive);
Chong Zhang198afac2016-04-15 12:03:11 -07001254
Bryce Leef3c6a472017-11-14 14:53:06 -08001255 mTmpAdjustedBounds.set(getRawBounds());
Chong Zhangf347ab52016-04-18 21:02:01 -07001256 // Account for the adjustment for IME and divider width separately.
1257 // (top - topBeforeImeAdjust) is the amount of movement due to IME only,
1258 // and dividerWidthDelta is due to divider width change only.
Bryce Leef3c6a472017-11-14 14:53:06 -08001259 mTmpAdjustedBounds.top = getRawBounds().top +
Chong Zhangf347ab52016-04-18 21:02:01 -07001260 (int) (mAdjustImeAmount * (top - topBeforeImeAdjust) +
1261 mAdjustDividerAmount * dividerWidthDelta);
Bryce Leef3c6a472017-11-14 14:53:06 -08001262 mFullyAdjustedImeBounds.set(getRawBounds());
Jorim Jaggieb88d832016-04-13 20:17:43 -07001263 mFullyAdjustedImeBounds.top = top;
Bryce Leef3c6a472017-11-14 14:53:06 -08001264 mFullyAdjustedImeBounds.bottom = top + getRawBounds().height();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001265 }
1266 return true;
1267 }
1268
1269 private boolean adjustForMinimizedDockedStack(float minimizeAmount) {
1270 final int dockSide = getDockSide();
1271 if (dockSide == DOCKED_INVALID && !mTmpAdjustedBounds.isEmpty()) {
1272 return false;
1273 }
1274
1275 if (dockSide == DOCKED_TOP) {
Winson Chung303c6b72016-10-24 17:12:49 -07001276 mService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001277 int topInset = mTmpRect.top;
Bryce Leef3c6a472017-11-14 14:53:06 -08001278 mTmpAdjustedBounds.set(getRawBounds());
1279 mTmpAdjustedBounds.bottom = (int) (minimizeAmount * topInset + (1 - minimizeAmount)
1280 * getRawBounds().bottom);
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001281 } else if (dockSide == DOCKED_LEFT) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001282 mTmpAdjustedBounds.set(getRawBounds());
1283 final int width = getRawBounds().width();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001284 mTmpAdjustedBounds.right =
1285 (int) (minimizeAmount * mDockedStackMinimizeThickness
Bryce Leef3c6a472017-11-14 14:53:06 -08001286 + (1 - minimizeAmount) * getRawBounds().right);
Jorim Jaggibcff1432016-04-01 15:49:45 -07001287 mTmpAdjustedBounds.left = mTmpAdjustedBounds.right - width;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001288 } else if (dockSide == DOCKED_RIGHT) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001289 mTmpAdjustedBounds.set(getRawBounds());
1290 mTmpAdjustedBounds.left = (int) (minimizeAmount *
1291 (getRawBounds().right - mDockedStackMinimizeThickness)
1292 + (1 - minimizeAmount) * getRawBounds().left);
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001293 }
1294 return true;
1295 }
1296
Matthew Nge15352e2016-12-20 15:36:29 -08001297 private boolean isMinimizedDockAndHomeStackResizable() {
1298 return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
1299 && mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
1300 }
1301
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001302 /**
Jorim Jaggif97ed922016-02-18 18:57:07 -08001303 * @return the distance in pixels how much the stack gets minimized from it's original size
1304 */
1305 int getMinimizeDistance() {
1306 final int dockSide = getDockSide();
1307 if (dockSide == DOCKED_INVALID) {
1308 return 0;
1309 }
1310
1311 if (dockSide == DOCKED_TOP) {
Winson Chung303c6b72016-10-24 17:12:49 -07001312 mService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
Jorim Jaggif97ed922016-02-18 18:57:07 -08001313 int topInset = mTmpRect.top;
Bryce Leef3c6a472017-11-14 14:53:06 -08001314 return getRawBounds().bottom - topInset;
Jorim Jaggif97ed922016-02-18 18:57:07 -08001315 } else if (dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001316 return getRawBounds().width() - mDockedStackMinimizeThickness;
Jorim Jaggif97ed922016-02-18 18:57:07 -08001317 } else {
1318 return 0;
1319 }
1320 }
1321
1322 /**
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001323 * Updates the adjustment depending on it's current state.
1324 */
Chong Zhang5117e272016-05-03 12:47:34 -07001325 private void updateAdjustedBounds() {
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001326 boolean adjust = false;
1327 if (mMinimizeAmount != 0f) {
1328 adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
1329 } else if (mAdjustedForIme) {
1330 adjust = adjustForIME(mImeWin);
1331 }
1332 if (!adjust) {
1333 mTmpAdjustedBounds.setEmpty();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001334 }
Jorim Jaggieb88d832016-04-13 20:17:43 -07001335 setAdjustedBounds(mTmpAdjustedBounds);
Chong Zhang198afac2016-04-15 12:03:11 -07001336
Chong Zhangb8da4a72016-05-17 15:07:26 -07001337 final boolean isImeTarget = (mService.getImeFocusStackLocked() == this);
Chong Zhangf347ab52016-04-18 21:02:01 -07001338 if (mAdjustedForIme && adjust && !isImeTarget) {
1339 final float alpha = Math.max(mAdjustImeAmount, mAdjustDividerAmount)
1340 * IME_ADJUST_DIM_AMOUNT;
Wale Ogunwale68278562017-09-23 17:13:55 -07001341 mService.setResizeDimLayer(true, getWindowingMode(), alpha);
Chong Zhang198afac2016-04-15 12:03:11 -07001342 }
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001343 }
1344
Chong Zhang5117e272016-05-03 12:47:34 -07001345 void applyAdjustForImeIfNeeded(Task task) {
1346 if (mMinimizeAmount != 0f || !mAdjustedForIme || mAdjustedBounds.isEmpty()) {
1347 return;
1348 }
1349
Bryce Leef3c6a472017-11-14 14:53:06 -08001350 final Rect insetBounds = mImeGoingAway ? getRawBounds() : mFullyAdjustedImeBounds;
Chong Zhang5117e272016-05-03 12:47:34 -07001351 task.alignToAdjustedBounds(mAdjustedBounds, insetBounds, getDockSide() == DOCKED_TOP);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001352 mDisplayContent.setLayoutNeeded();
Chong Zhang5117e272016-05-03 12:47:34 -07001353 }
1354
Bryce Leef3c6a472017-11-14 14:53:06 -08001355
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001356 boolean isAdjustedForMinimizedDockedStack() {
1357 return mMinimizeAmount != 0f;
1358 }
1359
Winson Chungd41f71d2018-03-16 15:26:07 -07001360 /**
1361 * @return {@code true} if we have a {@link Task} that is animating (currently only used for the
1362 * recents animation); {@code false} otherwise.
1363 */
1364 boolean isTaskAnimating() {
1365 for (int j = mChildren.size() - 1; j >= 0; j--) {
1366 final Task task = mChildren.get(j);
1367 if (task.isTaskAnimating()) {
1368 return true;
1369 }
1370 }
1371 return false;
1372 }
1373
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001374 @CallSuper
1375 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02001376 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07001377 final long token = proto.start(fieldId);
Adrian Roos4921ccf2017-09-28 16:54:06 +02001378 super.writeToProto(proto, WINDOW_CONTAINER, trim);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001379 proto.write(ID, mStackId);
1380 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
Adrian Roos4921ccf2017-09-28 16:54:06 +02001381 mChildren.get(taskNdx).writeToProto(proto, TASKS, trim);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001382 }
Bryce Leef3c6a472017-11-14 14:53:06 -08001383 proto.write(FILLS_PARENT, matchParentBounds());
1384 getRawBounds().writeToProto(proto, BOUNDS);
Robert Carrf59b8dd2017-10-02 18:58:36 -07001385 proto.write(ANIMATION_BACKGROUND_SURFACE_IS_DIMMING, mAnimationBackgroundSurfaceIsShown);
Vishnu Nair04ab4392018-01-10 11:00:06 -08001386 proto.write(DEFER_REMOVAL, mDeferRemoval);
1387 proto.write(MINIMIZE_AMOUNT, mMinimizeAmount);
1388 proto.write(ADJUSTED_FOR_IME, mAdjustedForIme);
1389 proto.write(ADJUST_IME_AMOUNT, mAdjustImeAmount);
1390 proto.write(ADJUST_DIVIDER_AMOUNT, mAdjustDividerAmount);
1391 mAdjustedBounds.writeToProto(proto, ADJUSTED_BOUNDS);
Winson Chung82267ce2018-04-06 16:38:26 -07001392 proto.write(ANIMATING_BOUNDS, mBoundsAnimating);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001393 proto.end(token);
1394 }
1395
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001396 @Override
1397 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
Wale Ogunwaleb429e682016-01-06 12:36:34 -08001398 pw.println(prefix + "mStackId=" + mStackId);
Wale Ogunwale10124582016-09-15 20:25:50 -07001399 pw.println(prefix + "mDeferRemoval=" + mDeferRemoval);
Bryce Leef3c6a472017-11-14 14:53:06 -08001400 pw.println(prefix + "mBounds=" + getRawBounds().toShortString());
Jorim Jaggiaf558e12016-04-27 22:56:56 -07001401 if (mMinimizeAmount != 0f) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001402 pw.println(prefix + "mMinimizeAmount=" + mMinimizeAmount);
Jorim Jaggiaf558e12016-04-27 22:56:56 -07001403 }
1404 if (mAdjustedForIme) {
1405 pw.println(prefix + "mAdjustedForIme=true");
1406 pw.println(prefix + "mAdjustImeAmount=" + mAdjustImeAmount);
1407 pw.println(prefix + "mAdjustDividerAmount=" + mAdjustDividerAmount);
1408 }
Jorim Jaggieb88d832016-04-13 20:17:43 -07001409 if (!mAdjustedBounds.isEmpty()) {
1410 pw.println(prefix + "mAdjustedBounds=" + mAdjustedBounds.toShortString());
1411 }
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001412 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001413 mChildren.get(taskNdx).dump(pw, prefix + " ", dumpAll);
Craig Mautner00af9fe2013-03-25 09:13:41 -07001414 }
Robert Carrf59b8dd2017-10-02 18:58:36 -07001415 if (mAnimationBackgroundSurfaceIsShown) {
1416 pw.println(prefix + "mWindowAnimationBackgroundSurface is shown");
Craig Mautner05d29032013-05-03 13:40:13 -07001417 }
Craig Mautnerdc548482014-02-05 13:35:24 -08001418 if (!mExitingAppTokens.isEmpty()) {
1419 pw.println();
1420 pw.println(" Exiting application tokens:");
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001421 for (int i = mExitingAppTokens.size() - 1; i >= 0; i--) {
Craig Mautnerdc548482014-02-05 13:35:24 -08001422 WindowToken token = mExitingAppTokens.get(i);
1423 pw.print(" Exiting App #"); pw.print(i);
1424 pw.print(' '); pw.print(token);
1425 pw.println(':');
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001426 token.dump(pw, " ", dumpAll);
Craig Mautnerdc548482014-02-05 13:35:24 -08001427 }
1428 }
Jorim Jaggib8a9cbe2018-03-27 18:02:18 +02001429 mAnimatingAppWindowTokenRegistry.dump(pw, "AnimatingApps:", prefix);
Craig Mautner00af9fe2013-03-25 09:13:41 -07001430 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001431
1432 @Override
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001433 boolean fillsParent() {
Wale Ogunwalef175e8a2015-09-29 11:07:06 -07001434 if (useCurrentBounds()) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001435 return matchParentBounds();
Wale Ogunwalef175e8a2015-09-29 11:07:06 -07001436 }
1437 // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
1438 // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
1439 // system.
1440 return true;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001441 }
1442
1443 @Override
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001444 public String toString() {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001445 return "{stackId=" + mStackId + " tasks=" + mChildren + "}";
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001446 }
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001447
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001448 String getName() {
1449 return toShortString();
1450 }
1451
Filip Gruszczynski0689ae92015-10-01 12:30:31 -07001452 public String toShortString() {
1453 return "Stack=" + mStackId;
1454 }
1455
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001456 /**
Chong Zhangc806d902015-11-30 09:44:27 -08001457 * For docked workspace (or workspace that's side-by-side to the docked), provides
1458 * information which side of the screen was the dock anchored.
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001459 */
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001460 int getDockSide() {
Bryce Leef3c6a472017-11-14 14:53:06 -08001461 return getDockSide(getRawBounds());
Jorim Jaggi737af722015-12-31 10:42:27 +01001462 }
1463
Matthew Nge8b052a2018-01-16 14:33:47 -08001464 int getDockSideForDisplay(DisplayContent dc) {
1465 return getDockSide(dc, getRawBounds());
1466 }
1467
Wale Ogunwale926aade2017-08-29 11:24:37 -07001468 private int getDockSide(Rect bounds) {
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001469 if (mDisplayContent == null) {
1470 return DOCKED_INVALID;
1471 }
Matthew Nge8b052a2018-01-16 14:33:47 -08001472 return getDockSide(mDisplayContent, bounds);
1473 }
1474
1475 private int getDockSide(DisplayContent dc, Rect bounds) {
1476 if (!inSplitScreenWindowingMode()) {
1477 return DOCKED_INVALID;
1478 }
1479 dc.getBounds(mTmpRect);
1480 final int orientation = dc.getConfiguration().orientation;
Matthew Ng62c78462018-04-09 14:43:21 -07001481 return dc.getDockedDividerController().getDockSide(bounds, mTmpRect, orientation);
Filip Gruszczynski923f8262015-09-17 17:41:13 -07001482 }
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -07001483
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001484 boolean hasTaskForUser(int userId) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001485 for (int i = mChildren.size() - 1; i >= 0; i--) {
1486 final Task task = mChildren.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001487 if (task.mUserId == userId) {
1488 return true;
1489 }
1490 }
1491 return false;
1492 }
1493
1494 int taskIdFromPoint(int x, int y) {
1495 getBounds(mTmpRect);
1496 if (!mTmpRect.contains(x, y) || isAdjustedForMinimizedDockedStack()) {
1497 return -1;
1498 }
1499
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001500 for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
1501 final Task task = mChildren.get(taskNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001502 final WindowState win = task.getTopVisibleAppMainWindow();
1503 if (win == null) {
1504 continue;
1505 }
1506 // We need to use the task's dim bounds (which is derived from the visible bounds of its
1507 // apps windows) for any touch-related tests. Can't use the task's original bounds
1508 // because it might be adjusted to fit the content frame. For example, the presence of
1509 // the IME adjusting the windows frames when the app window is the IME target.
1510 task.getDimBounds(mTmpRect);
1511 if (mTmpRect.contains(x, y)) {
1512 return task.mTaskId;
1513 }
1514 }
1515
1516 return -1;
1517 }
1518
1519 void findTaskForResizePoint(int x, int y, int delta,
1520 DisplayContent.TaskForResizePointSearchResult results) {
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001521 if (!getWindowConfiguration().canResizeTask()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001522 results.searchDone = true;
1523 return;
1524 }
1525
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001526 for (int i = mChildren.size() - 1; i >= 0; --i) {
1527 final Task task = mChildren.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001528 if (task.isFullscreen()) {
1529 results.searchDone = true;
1530 return;
1531 }
1532
1533 // We need to use the task's dim bounds (which is derived from the visible bounds of
1534 // its apps windows) for any touch-related tests. Can't use the task's original
1535 // bounds because it might be adjusted to fit the content frame. One example is when
1536 // the task is put to top-left quadrant, the actual visible area would not start at
1537 // (0,0) after it's adjusted for the status bar.
1538 task.getDimBounds(mTmpRect);
1539 mTmpRect.inset(-delta, -delta);
1540 if (mTmpRect.contains(x, y)) {
1541 mTmpRect.inset(delta, delta);
1542
1543 results.searchDone = true;
1544
1545 if (!mTmpRect.contains(x, y)) {
1546 results.taskForResize = task;
1547 return;
1548 }
1549 // User touched inside the task. No need to look further,
1550 // focus transfer will be handled in ACTION_UP.
1551 return;
1552 }
1553 }
1554 }
1555
1556 void setTouchExcludeRegion(Task focusedTask, int delta, Region touchExcludeRegion,
1557 Rect contentRect, Rect postExclude) {
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001558 for (int i = mChildren.size() - 1; i >= 0; --i) {
1559 final Task task = mChildren.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001560 AppWindowToken token = task.getTopVisibleAppToken();
1561 if (token == null || !token.hasContentToDisplay()) {
1562 continue;
1563 }
1564
1565 /**
1566 * Exclusion region is the region that TapDetector doesn't care about.
1567 * Here we want to remove all non-focused tasks from the exclusion region.
1568 * We also remove the outside touch area for resizing for all freeform
1569 * tasks (including the focused).
1570 *
1571 * We save the focused task region once we find it, and add it back at the end.
Matthew Nge15352e2016-12-20 15:36:29 -08001572 *
1573 * If the task is home stack and it is resizable in the minimized state, we want to
1574 * exclude the docked stack from touch so we need the entire screen area and not just a
1575 * small portion which the home stack currently is resized to.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001576 */
1577
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -07001578 if (task.isActivityTypeHome() && isMinimizedDockAndHomeStackResizable()) {
Bryce Leef3c6a472017-11-14 14:53:06 -08001579 mDisplayContent.getBounds(mTmpRect);
Matthew Nge15352e2016-12-20 15:36:29 -08001580 } else {
1581 task.getDimBounds(mTmpRect);
1582 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001583
1584 if (task == focusedTask) {
1585 // Add the focused task rect back into the exclude region once we are done
1586 // processing stacks.
1587 postExclude.set(mTmpRect);
1588 }
1589
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001590 final boolean isFreeformed = task.inFreeformWindowingMode();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001591 if (task != focusedTask || isFreeformed) {
1592 if (isFreeformed) {
1593 // If the task is freeformed, enlarge the area to account for outside
1594 // touch area for resize.
1595 mTmpRect.inset(-delta, -delta);
1596 // Intersect with display content rect. If we have system decor (status bar/
1597 // navigation bar), we want to exclude that from the tap detection.
1598 // Otherwise, if the app is partially placed under some system button (eg.
1599 // Recents, Home), pressing that button would cause a full series of
1600 // unwanted transfer focus/resume/pause, before we could go home.
1601 mTmpRect.intersect(contentRect);
1602 }
1603 touchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
1604 }
1605 }
1606 }
1607
Winson Chung8bca9e42017-04-16 15:59:43 -07001608 public boolean setPinnedStackSize(Rect stackBounds, Rect tempTaskBounds) {
1609 // Hold the lock since this is called from the BoundsAnimator running on the UiThread
1610 synchronized (mService.mWindowMap) {
1611 if (mCancelCurrentBoundsAnimation) {
1612 return false;
1613 }
Winson Chung19953ca2017-04-11 11:19:23 -07001614 }
1615
Robert Carr0d00c2e2016-02-29 17:45:02 -08001616 try {
Winson Chung8bca9e42017-04-16 15:59:43 -07001617 mService.mActivityManager.resizePinnedStack(stackBounds, tempTaskBounds);
Robert Carr0d00c2e2016-02-29 17:45:02 -08001618 } catch (RemoteException e) {
1619 // I don't believe you.
1620 }
1621 return true;
1622 }
1623
Robert Carrecc06b32017-04-18 14:25:10 -07001624 void onAllWindowsDrawn() {
Winson Chunge7ba6862017-05-24 12:13:33 -07001625 if (!mBoundsAnimating && !mBoundsAnimatingRequested) {
Robert Carrecc06b32017-04-18 14:25:10 -07001626 return;
1627 }
1628
1629 mService.mBoundsAnimationController.onAllWindowsDrawn();
1630 }
1631
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001632 @Override // AnimatesBounds
Winson Chungab76bbc2017-08-14 13:33:51 -07001633 public void onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate) {
Winson Chung8bca9e42017-04-16 15:59:43 -07001634 // Hold the lock since this is called from the BoundsAnimator running on the UiThread
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001635 synchronized (mService.mWindowMap) {
Winson Chung40a5f932017-04-13 16:39:36 -07001636 mBoundsAnimatingRequested = false;
Robert Carr1ca6a332016-04-11 18:00:43 -07001637 mBoundsAnimating = true;
Winson Chung19953ca2017-04-11 11:19:23 -07001638 mCancelCurrentBoundsAnimation = false;
Robert Carrecc06b32017-04-18 14:25:10 -07001639
1640 // If we are changing UI mode, as in the PiP to fullscreen
1641 // transition, then we need to wait for the window to draw.
1642 if (schedulePipModeChangedCallback) {
1643 forAllWindows((w) -> { w.mWinAnimator.resetDrawState(); },
1644 false /* traverseTopToBottom */);
1645 }
Wale Ogunwalece144522016-02-05 22:51:01 -08001646 }
Winson Chung85d39982017-02-24 15:21:25 -08001647
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001648 if (inPinnedWindowingMode()) {
Winson Chung85d39982017-02-24 15:21:25 -08001649 try {
1650 mService.mActivityManager.notifyPinnedStackAnimationStarted();
1651 } catch (RemoteException e) {
1652 // I don't believe you...
1653 }
Winson Chung8bca9e42017-04-16 15:59:43 -07001654
1655 final PinnedStackWindowController controller =
1656 (PinnedStackWindowController) getController();
1657 if (schedulePipModeChangedCallback && controller != null) {
Winson Chungab76bbc2017-08-14 13:33:51 -07001658 // We need to schedule the PiP mode change before the animation up. It is possible
1659 // in this case for the animation down to not have been completed, so always
1660 // force-schedule and update to the client to ensure that it is notified that it
1661 // is no longer in picture-in-picture mode
1662 controller.updatePictureInPictureModeForPinnedStackAnimation(null, forceUpdate);
Winson Chung8bca9e42017-04-16 15:59:43 -07001663 }
Winson Chung85d39982017-02-24 15:21:25 -08001664 }
Wale Ogunwalece144522016-02-05 22:51:01 -08001665 }
1666
1667 @Override // AnimatesBounds
Winson Chung8bca9e42017-04-16 15:59:43 -07001668 public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
1669 boolean moveToFullscreen) {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001670 if (inPinnedWindowingMode()) {
Robert Carr18f622f2017-05-08 11:20:43 -07001671 // Update to the final bounds if requested. This is done here instead of in the bounds
1672 // animator to allow us to coordinate this after we notify the PiP mode changed
1673
Winson Chung8bca9e42017-04-16 15:59:43 -07001674 final PinnedStackWindowController controller =
1675 (PinnedStackWindowController) getController();
1676 if (schedulePipModeChangedCallback && controller != null) {
1677 // We need to schedule the PiP mode change after the animation down, so use the
1678 // final bounds
1679 controller.updatePictureInPictureModeForPinnedStackAnimation(
Winson Chungab76bbc2017-08-14 13:33:51 -07001680 mBoundsAnimationTarget, false /* forceUpdate */);
Winson Chung8bca9e42017-04-16 15:59:43 -07001681 }
1682
Winson Chung8bca9e42017-04-16 15:59:43 -07001683 if (finalStackSize != null) {
1684 setPinnedStackSize(finalStackSize, null);
Winson Chunge40082ea2018-06-05 16:03:12 -07001685 } else {
1686 // We have been canceled, so the final stack size is null, still run the
1687 // animation-end logic
1688 onPipAnimationEndResize();
Winson Chung8bca9e42017-04-16 15:59:43 -07001689 }
1690
Wale Ogunwale480dca02016-02-06 13:58:29 -08001691 try {
1692 mService.mActivityManager.notifyPinnedStackAnimationEnded();
Winson Chung8bca9e42017-04-16 15:59:43 -07001693 if (moveToFullscreen) {
1694 mService.mActivityManager.moveTasksToFullscreenStack(mStackId,
1695 true /* onTop */);
1696 }
Wale Ogunwale480dca02016-02-06 13:58:29 -08001697 } catch (RemoteException e) {
1698 // I don't believe you...
1699 }
Winson Chunge40082ea2018-06-05 16:03:12 -07001700 } else {
1701 // No PiP animation, just run the normal animation-end logic
1702 onPipAnimationEndResize();
Wale Ogunwale480dca02016-02-06 13:58:29 -08001703 }
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08001704 }
Filip Gruszczynskic17d8b72016-02-03 16:52:59 -08001705
Winson Chung15036ca2018-05-31 15:51:47 -07001706 /**
1707 * Called immediately prior to resizing the tasks at the end of the pinned stack animation.
1708 */
1709 public void onPipAnimationEndResize() {
1710 mBoundsAnimating = false;
1711 for (int i = 0; i < mChildren.size(); i++) {
1712 final Task t = mChildren.get(i);
1713 t.clearPreserveNonFloatingState();
1714 }
1715 mService.requestTraversal();
1716 }
1717
Winson Chung6a38fca2018-03-28 17:57:09 -07001718 @Override
1719 public boolean shouldDeferStartOnMoveToFullscreen() {
1720 // Workaround for the recents animation -- normally we need to wait for the new activity to
1721 // show before starting the PiP animation, but because we start and show the home activity
1722 // early for the recents animation prior to the PiP animation starting, there is no
1723 // subsequent all-drawn signal. In this case, we can skip the pause when the home stack is
1724 // already visible and drawn.
1725 final TaskStack homeStack = mDisplayContent.getHomeStack();
1726 if (homeStack == null) {
1727 return true;
1728 }
1729 final Task homeTask = homeStack.getTopChild();
Winson Chungf91dbf72018-04-18 11:42:30 -07001730 if (homeTask == null) {
1731 return true;
1732 }
Winson Chung6a38fca2018-03-28 17:57:09 -07001733 final AppWindowToken homeApp = homeTask.getTopVisibleAppToken();
1734 if (!homeTask.isVisible() || homeApp == null) {
1735 return true;
1736 }
1737 return !homeApp.allDrawn;
1738 }
1739
Winson Chung8bca9e42017-04-16 15:59:43 -07001740 /**
1741 * @return True if we are currently animating the pinned stack from fullscreen to non-fullscreen
1742 * bounds and we have a deferred PiP mode changed callback set with the animation.
1743 */
1744 public boolean deferScheduleMultiWindowModeChanged() {
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001745 if (inPinnedWindowingMode()) {
Winson Chung8bca9e42017-04-16 15:59:43 -07001746 return (mBoundsAnimatingRequested || mBoundsAnimating);
Filip Gruszczynskic17d8b72016-02-03 16:52:59 -08001747 }
Winson Chung8bca9e42017-04-16 15:59:43 -07001748 return false;
Filip Gruszczynskic17d8b72016-02-03 16:52:59 -08001749 }
1750
Robert Carr8f0a3ad2017-02-15 19:30:28 -08001751 public boolean isForceScaled() {
Robert Carr1ca6a332016-04-11 18:00:43 -07001752 return mBoundsAnimating;
1753 }
1754
Winson Chung40a5f932017-04-13 16:39:36 -07001755 public boolean isAnimatingBounds() {
Robert Carr1ca6a332016-04-11 18:00:43 -07001756 return mBoundsAnimating;
Robert Carr0d00c2e2016-02-29 17:45:02 -08001757 }
Jorim Jaggi6626f542016-08-22 13:08:44 -07001758
Robert Carr18f622f2017-05-08 11:20:43 -07001759 public boolean lastAnimatingBoundsWasToFullscreen() {
1760 return mBoundsAnimatingToFullscreen;
1761 }
1762
Winson Chung40a5f932017-04-13 16:39:36 -07001763 public boolean isAnimatingBoundsToFullscreen() {
Robert Carr18f622f2017-05-08 11:20:43 -07001764 return isAnimatingBounds() && lastAnimatingBoundsWasToFullscreen();
Robert Carr7e4c90e2017-02-15 19:52:38 -08001765 }
1766
Winson Chung8bca9e42017-04-16 15:59:43 -07001767 public boolean pinnedStackResizeDisallowed() {
Winson Chung19953ca2017-04-11 11:19:23 -07001768 if (mBoundsAnimating && mCancelCurrentBoundsAnimation) {
1769 return true;
1770 }
1771 return false;
1772 }
1773
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001774 /** Returns true if a removal action is still being deferred. */
1775 boolean checkCompleteDeferredRemoval() {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001776 if (isSelfOrChildAnimating()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001777 return true;
1778 }
Wale Ogunwale10124582016-09-15 20:25:50 -07001779 if (mDeferRemoval) {
1780 removeImmediately();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001781 }
1782
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001783 return super.checkCompleteDeferredRemoval();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001784 }
1785
Wale Ogunwale14a3fb92016-09-11 15:19:05 -07001786 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07001787 int getOrientation() {
Wale Ogunwale68278562017-09-23 17:13:55 -07001788 return (canSpecifyOrientation()) ? super.getOrientation() : SCREEN_ORIENTATION_UNSET;
1789 }
1790
1791 private boolean canSpecifyOrientation() {
1792 final int windowingMode = getWindowingMode();
1793 final int activityType = getActivityType();
1794 return windowingMode == WINDOWING_MODE_FULLSCREEN
1795 || activityType == ACTIVITY_TYPE_HOME
1796 || activityType == ACTIVITY_TYPE_RECENTS
1797 || activityType == ACTIVITY_TYPE_ASSISTANT;
Wale Ogunwale51362492016-09-08 17:49:17 -07001798 }
Robert Carrf59b8dd2017-10-02 18:58:36 -07001799
chaviw2fb06bc2018-01-19 17:09:15 -08001800 @Override
Robert Carrf59b8dd2017-10-02 18:58:36 -07001801 Dimmer getDimmer() {
1802 return mDimmer;
1803 }
1804
1805 @Override
1806 void prepareSurfaces() {
1807 mDimmer.resetDimStates();
1808 super.prepareSurfaces();
1809 getDimBounds(mTmpDimBoundsRect);
chaviwe07246a2017-12-12 16:18:29 -08001810
1811 // Bounds need to be relative, as the dim layer is a child.
1812 mTmpDimBoundsRect.offsetTo(0, 0);
Robert Carrf59b8dd2017-10-02 18:58:36 -07001813 if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
1814 scheduleAnimation();
1815 }
1816 }
1817
1818 public DisplayInfo getDisplayInfo() {
1819 return mDisplayContent.getDisplayInfo();
1820 }
1821
1822 void dim(float alpha) {
1823 mDimmer.dimAbove(getPendingTransaction(), alpha);
1824 scheduleAnimation();
1825 }
1826
1827 void stopDimming() {
1828 mDimmer.stopDim(getPendingTransaction());
1829 scheduleAnimation();
1830 }
Robert Carr32bcb102018-01-29 15:03:23 -08001831
1832 @Override
1833 void getRelativePosition(Point outPos) {
1834 super.getRelativePosition(outPos);
1835 final int outset = getStackOutset();
1836 outPos.x -= outset;
1837 outPos.y -= outset;
1838 }
Jorim Jaggi6de61012018-03-19 14:53:23 +01001839
1840 AnimatingAppWindowTokenRegistry getAnimatingAppWindowTokenRegistry() {
1841 return mAnimatingAppWindowTokenRegistry;
1842 }
Wale Ogunwaleecbcadd2016-02-21 14:18:51 -08001843}