blob: 3e78d5ef0f65ff60aae7be54bc8fc44db8e2c1ad [file] [log] [blame]
Wale Ogunwaled63594a2016-07-18 07:48:30 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
Jorim Jaggi612bb882017-05-16 17:11:18 +020019import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
20import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
21import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Wale Ogunwaleda8b8272018-11-29 19:37:37 -080022import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
23import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
24import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
25import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
26import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
lumark19a5d2e2019-10-11 16:19:30 +080027import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
Vishnu Nair04ab4392018-01-10 11:00:06 -080028import static android.view.SurfaceControl.Transaction;
Louis Chang7501e332018-08-20 13:08:39 +080029
lumark19a5d2e2019-10-11 16:19:30 +080030import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
31import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
32import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
lumark9bca6b42019-10-17 18:35:22 +080033import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
34import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
35import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070036import static com.android.server.wm.WindowContainerProto.CONFIGURATION_CONTAINER;
37import static com.android.server.wm.WindowContainerProto.ORIENTATION;
38import static com.android.server.wm.WindowContainerProto.SURFACE_ANIMATOR;
39import static com.android.server.wm.WindowContainerProto.VISIBLE;
Louis Chang7501e332018-08-20 13:08:39 +080040import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
41import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
42import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
lumark19a5d2e2019-10-11 16:19:30 +080043import static com.android.server.wm.WindowManagerService.logWithStack;
Yunfan Chen87b5a242019-10-01 17:53:59 +090044import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
lumark19a5d2e2019-10-11 16:19:30 +080045import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
Jorim Jaggi612bb882017-05-16 17:11:18 +020046
Wale Ogunwaled63594a2016-07-18 07:48:30 -070047import android.annotation.CallSuper;
Jorim Jaggi391790622018-04-18 15:30:44 +020048import android.annotation.IntDef;
Garfield Tan90b04282018-12-11 14:04:42 -080049import android.annotation.Nullable;
Jorim Jaggi391790622018-04-18 15:30:44 +020050import android.app.WindowConfiguration;
Wale Ogunwaleda8b8272018-11-29 19:37:37 -080051import android.content.pm.ActivityInfo;
Andrii Kulian441e4492016-09-29 15:25:00 -070052import android.content.res.Configuration;
chaviwe07246a2017-12-12 16:18:29 -080053import android.graphics.Point;
54import android.graphics.Rect;
Wale Ogunwaleda8b8272018-11-29 19:37:37 -080055import android.os.Debug;
Garfield Tan90b04282018-12-11 14:04:42 -080056import android.os.IBinder;
lumark19a5d2e2019-10-11 16:19:30 +080057import android.os.Trace;
58import android.util.Pair;
Vishnu Nair04ab4392018-01-10 11:00:06 -080059import android.util.Pools;
Jorim Jaggia5e10572017-11-15 14:36:26 +010060import android.util.Slog;
Vishnu Nair04ab4392018-01-10 11:00:06 -080061import android.util.proto.ProtoOutputStream;
lumark19a5d2e2019-10-11 16:19:30 +080062import android.view.DisplayInfo;
Robert Carrb1579c82017-09-05 14:54:47 -070063import android.view.MagnificationSpec;
lumark19a5d2e2019-10-11 16:19:30 +080064import android.view.RemoteAnimationTarget;
Robert Carrb1579c82017-09-05 14:54:47 -070065import android.view.SurfaceControl;
Jorim Jaggia5e10572017-11-15 14:36:26 +010066import android.view.SurfaceControl.Builder;
Robert Carrb1579c82017-09-05 14:54:47 -070067import android.view.SurfaceSession;
lumark19a5d2e2019-10-11 16:19:30 +080068import android.view.WindowManager;
69import android.view.animation.Animation;
Garfield Tan2f145f22018-11-01 15:27:03 -070070
Evan Rosky65dffa62019-02-04 14:09:53 -080071import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggia5e10572017-11-15 14:36:26 +010072import com.android.internal.util.ToBooleanFunction;
Yunfan Chen87b5a242019-10-01 17:53:59 +090073import com.android.server.policy.WindowManagerPolicy;
lumark19a5d2e2019-10-11 16:19:30 +080074import com.android.server.protolog.common.ProtoLog;
Jorim Jaggia5e10572017-11-15 14:36:26 +010075import com.android.server.wm.SurfaceAnimator.Animatable;
Garfield Tan2f145f22018-11-01 15:27:03 -070076
Jorim Jaggia5e10572017-11-15 14:36:26 +010077import java.io.PrintWriter;
Yunfan Chen87b5a242019-10-01 17:53:59 +090078import java.util.ArrayList;
Wale Ogunwaled63594a2016-07-18 07:48:30 -070079import java.util.Comparator;
80import java.util.LinkedList;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -070081import java.util.function.Consumer;
Wale Ogunwaled1880962016-11-08 10:31:59 -080082import java.util.function.Predicate;
Wale Ogunwaled63594a2016-07-18 07:48:30 -070083
84/**
85 * Defines common functionality for classes that can hold windows directly or through their
Wale Ogunwale51362492016-09-08 17:49:17 -070086 * children in a hierarchy form.
Wale Ogunwaled63594a2016-07-18 07:48:30 -070087 * The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime
88 * changes are made to this class.
89 */
Wale Ogunwale98d62312017-07-12 09:24:56 -070090class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
Jorim Jaggia5e10572017-11-15 14:36:26 +010091 implements Comparable<WindowContainer>, Animatable {
92
93 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainer" : TAG_WM;
Wale Ogunwaled63594a2016-07-18 07:48:30 -070094
Louis Changdc077272019-11-12 16:52:56 +080095 /** Animation layer that happens above all animating {@link ActivityStack}s. */
Jorim Jaggi391790622018-04-18 15:30:44 +020096 static final int ANIMATION_LAYER_STANDARD = 0;
97
Louis Changdc077272019-11-12 16:52:56 +080098 /** Animation layer that happens above all {@link ActivityStack}s. */
Jorim Jaggi391790622018-04-18 15:30:44 +020099 static final int ANIMATION_LAYER_BOOSTED = 1;
100
101 /**
102 * Animation layer that is reserved for {@link WindowConfiguration#ACTIVITY_TYPE_HOME}
Winson Chung732446a2018-09-19 13:15:17 -0700103 * activities and all activities that are being controlled by the recents animation. This
Louis Changdc077272019-11-12 16:52:56 +0800104 * layer is generally below all {@link ActivityStack}s.
Jorim Jaggi391790622018-04-18 15:30:44 +0200105 */
106 static final int ANIMATION_LAYER_HOME = 2;
107
108 @IntDef(prefix = { "ANIMATION_LAYER_" }, value = {
109 ANIMATION_LAYER_STANDARD,
110 ANIMATION_LAYER_BOOSTED,
111 ANIMATION_LAYER_HOME,
112 })
113 @interface AnimationLayer {}
114
Andrii Kuliand2765632016-12-12 22:26:34 -0800115 static final int POSITION_TOP = Integer.MAX_VALUE;
116 static final int POSITION_BOTTOM = Integer.MIN_VALUE;
117
Andrii Kulian441e4492016-09-29 15:25:00 -0700118 /**
119 * The parent of this window container.
120 * For removing or setting new parent {@link #setParent} should be used, because it also
121 * performs configuration updates based on new parent's settings.
122 */
Jorim Jaggia5e10572017-11-15 14:36:26 +0100123 private WindowContainer<WindowContainer> mParent = null;
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700124
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200125 // Set to true when we are performing a reparenting operation so we only send one
126 // onParentChanged() notification.
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700127 boolean mReparenting;
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200128
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700129 // List of children for this window container. List is in z-order as the children appear on
130 // screen with the top-most window container at the tail of the list.
Jorim Jaggi612bb882017-05-16 17:11:18 +0200131 protected final WindowList<E> mChildren = new WindowList<E>();
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700132
Wale Ogunwale51362492016-09-08 17:49:17 -0700133 // The specified orientation for this window container.
134 protected int mOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
135
Wale Ogunwaleee41d4a2016-11-21 08:41:10 -0800136 private final Pools.SynchronizedPool<ForAllWindowsConsumerWrapper> mConsumerWrapperPool =
137 new Pools.SynchronizedPool<>(3);
138
Tiger Huanged6794e2019-05-07 20:07:59 +0800139 // The display this window container is on.
140 protected DisplayContent mDisplayContent;
141
Robert Carrb1579c82017-09-05 14:54:47 -0700142 protected SurfaceControl mSurfaceControl;
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100143 private int mLastLayer = 0;
144 private SurfaceControl mLastRelativeToLayer = null;
Robert Carrb1579c82017-09-05 14:54:47 -0700145
Tiger Huanged6794e2019-05-07 20:07:59 +0800146 // TODO(b/132320879): Remove this from WindowContainers except DisplayContent.
147 private final Transaction mPendingTransaction;
148
Robert Carrb1579c82017-09-05 14:54:47 -0700149 /**
Yunfan Chen87b5a242019-10-01 17:53:59 +0900150 * Windows that clients are waiting to have drawn.
151 */
152 final ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
153
154 /**
Robert Carrb1579c82017-09-05 14:54:47 -0700155 * Applied as part of the animation pass in "prepareSurfaces".
156 */
Jorim Jaggia5e10572017-11-15 14:36:26 +0100157 protected final SurfaceAnimator mSurfaceAnimator;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800158 protected final WindowManagerService mWmService;
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100159
chaviwe07246a2017-12-12 16:18:29 -0800160 private final Point mTmpPos = new Point();
chaviw3e751af2018-01-11 11:22:39 -0800161 protected final Point mLastSurfacePosition = new Point();
chaviwe07246a2017-12-12 16:18:29 -0800162
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100163 /** Total number of elements in this subtree, including our own hierarchy element. */
164 private int mTreeWeight = 1;
165
chaviw7f1fa992018-01-10 13:52:12 -0800166 /**
Vishnu Nairddd80742018-08-21 14:12:46 -0700167 * Indicates whether we are animating and have committed the transaction to reparent our
chaviw7f1fa992018-01-10 13:52:12 -0800168 * surface to the animation leash
169 */
170 private boolean mCommittedReparentToAnimationLeash;
171
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800172 private final Configuration mTmpConfig = new Configuration();
173
lumark9bca6b42019-10-17 18:35:22 +0800174 /** Interface for {@link #isAnimating} to check which cases for the container is animating. */
175 public interface AnimationFlags {
176 /**
177 * A bit flag indicates that {@link #isAnimating} should also return {@code true}
178 * even though the container is not yet animating, but the window container or its
179 * relatives as specified by PARENTS or CHILDREN are part of an {@link AppTransition}
180 * that is pending so an animation starts soon.
181 */
182 int TRANSITION = 1;
183
184 /**
185 * A bit flag indicates that {@link #isAnimating} should also check if one of the
186 * ancestors of the container are animating in addition to the container itself.
187 */
188 int PARENTS = 2;
189
190 /**
191 * A bit flag indicates that {@link #isAnimating} should also check if one of the
192 * descendants of the container are animating in addition to the container itself.
193 */
194 int CHILDREN = 4;
195 }
196
Issei Suzuki25a9e2b2019-08-14 16:46:26 +0200197 /**
198 * Callback which is triggered while changing the parent, after setting up the surface but
199 * before asking the parent to assign child layers.
200 */
201 interface PreAssignChildLayersCallback {
202 void onPreAssignChildLayers();
203 }
204
lumark19a5d2e2019-10-11 16:19:30 +0800205 /**
206 * True if this an AppWindowToken and the activity which created this was launched with
207 * ActivityOptions.setLaunchTaskBehind.
208 *
209 * TODO(b/142617871): We run a special animation when the activity was launched with that
210 * flag, but it's not necessary anymore. Keep the window invisible until the task is explicitly
211 * selected to suppress an animation, and remove this flag.
212 */
213 boolean mLaunchTaskBehind;
214
215 /**
216 * If we are running an animation, this determines the transition type. Must be one of
217 * {@link AppTransition#TransitionFlags}.
218 */
219 int mTransit;
220
221 /**
222 * If we are running an animation, this determines the flags during this animation. Must be a
223 * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
224 */
225 int mTransitFlags;
226
227 /** Whether this container should be boosted at the top of all its siblings. */
228 @VisibleForTesting boolean mNeedsZBoost;
229
230 /** Layer used to constrain the animation to a container's stack bounds. */
231 SurfaceControl mAnimationBoundsLayer;
232
233 /** Whether this container needs to create mAnimationBoundsLayer for cropping animations. */
234 boolean mNeedsAnimationBoundsLayer;
235
236 /**
237 * This gets used during some open/close transitions as well as during a change transition
238 * where it represents the starting-state snapshot.
239 */
lumarkbc0032a2019-11-01 21:38:13 +0800240 WindowContainerThumbnail mThumbnail;
lumark19a5d2e2019-10-11 16:19:30 +0800241 final Rect mTransitStartRect = new Rect();
242 final Point mTmpPoint = new Point();
243 protected final Rect mTmpRect = new Rect();
244 final Rect mTmpPrevBounds = new Rect();
245
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800246 WindowContainer(WindowManagerService wms) {
247 mWmService = wms;
Vishnu Nair33197392019-08-30 10:29:37 -0700248 mPendingTransaction = wms.mTransactionFactory.get();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800249 mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, wms);
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100250 }
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800251
Wale Ogunwale98d62312017-07-12 09:24:56 -0700252 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -0700253 final protected WindowContainer getParent() {
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700254 return mParent;
255 }
256
Wale Ogunwale98d62312017-07-12 09:24:56 -0700257 @Override
Wale Ogunwale61911492017-10-11 08:50:50 -0700258 protected int getChildCount() {
Wale Ogunwale98d62312017-07-12 09:24:56 -0700259 return mChildren.size();
260 }
261
262 @Override
Wale Ogunwale61911492017-10-11 08:50:50 -0700263 protected E getChildAt(int index) {
Wale Ogunwale98d62312017-07-12 09:24:56 -0700264 return mChildren.get(index);
265 }
266
chaviwe07246a2017-12-12 16:18:29 -0800267 @Override
268 public void onConfigurationChanged(Configuration newParentConfig) {
269 super.onConfigurationChanged(newParentConfig);
chaviw2f0567b2018-01-29 16:22:02 -0800270 updateSurfacePosition();
chaviwe07246a2017-12-12 16:18:29 -0800271 scheduleAnimation();
272 }
273
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200274 void reparent(WindowContainer newParent, int position) {
275 if (newParent == null) {
276 throw new IllegalArgumentException("reparent: can't reparent to null " + this);
277 }
278
279 final WindowContainer oldParent = mParent;
280 if (mParent == newParent) {
281 throw new IllegalArgumentException("WC=" + this + " already child of " + mParent);
282 }
283
284 // The display object before reparenting as that might lead to old parent getting removed
285 // from the display if it no longer has any child.
286 final DisplayContent prevDc = oldParent.getDisplayContent();
287 final DisplayContent dc = newParent.getDisplayContent();
288
289 mReparenting = true;
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700290 // Oddly enough we add to the new parent before removing from the old parent to avoid
291 // issues...
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200292 newParent.addChild(this, position);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700293 oldParent.removeChild(this);
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200294 mReparenting = false;
295
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200296 // Relayout display(s)
297 dc.setLayoutNeeded();
298 if (prevDc != dc) {
299 onDisplayChanged(dc);
300 prevDc.setLayoutNeeded();
301 }
302 getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700303
304 // Send onParentChanged notification here is we disabled sending it in setParent for
305 // reparenting case.
306 onParentChanged(newParent, oldParent);
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200307 }
308
Jorim Jaggia5e10572017-11-15 14:36:26 +0100309 final protected void setParent(WindowContainer<WindowContainer> parent) {
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200310 final WindowContainer oldParent = mParent;
Andrii Kulian441e4492016-09-29 15:25:00 -0700311 mParent = parent;
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200312 if (!mReparenting) {
313 onParentChanged(mParent, oldParent);
314 }
Andrii Kuliand2765632016-12-12 22:26:34 -0800315 }
316
317 /**
318 * Callback that is triggered when @link WindowContainer#setParent(WindowContainer)} was called.
319 * Supposed to be overridden and contain actions that should be executed after parent was set.
320 */
Riddle Hsu3a4bb612019-01-31 00:02:22 +0800321 @Override
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200322 void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
323 onParentChanged(newParent, oldParent, null);
Issei Suzuki25a9e2b2019-08-14 16:46:26 +0200324 }
325
Wale Ogunwalec17418e2019-10-13 23:00:40 +0200326 void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent,
327 PreAssignChildLayersCallback callback) {
328 super.onParentChanged(newParent, oldParent);
Robert Carrb1579c82017-09-05 14:54:47 -0700329 if (mParent == null) {
330 return;
331 }
Jorim Jaggia5e10572017-11-15 14:36:26 +0100332
Robert Carrb1579c82017-09-05 14:54:47 -0700333 if (mSurfaceControl == null) {
334 // If we don't yet have a surface, but we now have a parent, we should
335 // build a surface.
336 mSurfaceControl = makeSurface().build();
Robert Carrf59b8dd2017-10-02 18:58:36 -0700337 getPendingTransaction().show(mSurfaceControl);
Evan Roskyb1ea7ca2018-04-05 17:17:35 -0700338 updateSurfacePosition();
Robert Carrb1579c82017-09-05 14:54:47 -0700339 } else {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100340 // If we have a surface but a new parent, we just need to perform a reparent. Go through
341 // surface animator such that hierarchy is preserved when animating, i.e.
342 // mSurfaceControl stays attached to the leash and we just reparent the leash to the
343 // new parent.
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100344 reparentSurfaceControl(getPendingTransaction(), mParent.mSurfaceControl);
Robert Carrb1579c82017-09-05 14:54:47 -0700345 }
346
Issei Suzuki25a9e2b2019-08-14 16:46:26 +0200347 if (callback != null) {
348 callback.onPreAssignChildLayers();
349 }
350
Robert Carrb1579c82017-09-05 14:54:47 -0700351 // Either way we need to ask the parent to assign us a Z-order.
352 mParent.assignChildLayers();
353 scheduleAnimation();
Andrii Kulian441e4492016-09-29 15:25:00 -0700354 }
355
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700356 // Temp. holders for a chain of containers we are currently processing.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100357 private final LinkedList<WindowContainer> mTmpChain1 = new LinkedList<>();
358 private final LinkedList<WindowContainer> mTmpChain2 = new LinkedList<>();
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700359
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700360 /**
361 * Adds the input window container has a child of this container in order based on the input
362 * comparator.
363 * @param child The window container to add as a child of this window container.
364 * @param comparator Comparator to use in determining the position the child should be added to.
365 * If null, the child will be added to the top.
366 */
367 @CallSuper
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700368 protected void addChild(E child, Comparator<E> comparator) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700369 if (!child.mReparenting && child.getParent() != null) {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700370 throw new IllegalArgumentException("addChild: container=" + child.getName()
Andrii Kulian441e4492016-09-29 15:25:00 -0700371 + " is already a child of container=" + child.getParent().getName()
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700372 + " can't add to container=" + getName());
Wale Ogunwalef6192862016-09-10 13:42:30 -0700373 }
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700374
Andrii Kulianb94292e2016-10-19 13:30:58 -0700375 int positionToAdd = -1;
376 if (comparator != null) {
377 final int count = mChildren.size();
378 for (int i = 0; i < count; i++) {
379 if (comparator.compare(child, mChildren.get(i)) < 0) {
380 positionToAdd = i;
381 break;
382 }
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700383 }
384 }
385
Andrii Kulianb94292e2016-10-19 13:30:58 -0700386 if (positionToAdd == -1) {
387 mChildren.add(child);
388 } else {
389 mChildren.add(positionToAdd, child);
390 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100391 onChildAdded(child);
392
Andrii Kulianb94292e2016-10-19 13:30:58 -0700393 // Set the parent after we've actually added a child in case a subclass depends on this.
394 child.setParent(this);
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700395 }
396
Wale Ogunwalef6192862016-09-10 13:42:30 -0700397 /** Adds the input window container has a child of this container at the input index. */
398 @CallSuper
Wale Ogunwale72919d22016-12-08 18:58:50 -0800399 void addChild(E child, int index) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700400 if (!child.mReparenting && child.getParent() != null) {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700401 throw new IllegalArgumentException("addChild: container=" + child.getName()
Andrii Kulian441e4492016-09-29 15:25:00 -0700402 + " is already a child of container=" + child.getParent().getName()
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800403 + " can't add to container=" + getName()
404 + "\n callers=" + Debug.getCallers(15, "\n"));
Wale Ogunwalef6192862016-09-10 13:42:30 -0700405 }
Kazuki Takisef85197b2018-06-18 18:18:36 +0900406
407 if ((index < 0 && index != POSITION_BOTTOM)
408 || (index > mChildren.size() && index != POSITION_TOP)) {
409 throw new IllegalArgumentException("addChild: invalid position=" + index
410 + ", children number=" + mChildren.size());
411 }
412
413 if (index == POSITION_TOP) {
414 index = mChildren.size();
415 } else if (index == POSITION_BOTTOM) {
416 index = 0;
417 }
418
Wale Ogunwalef6192862016-09-10 13:42:30 -0700419 mChildren.add(index, child);
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100420 onChildAdded(child);
421
Andrii Kulianb94292e2016-10-19 13:30:58 -0700422 // Set the parent after we've actually added a child in case a subclass depends on this.
423 child.setParent(this);
Wale Ogunwalef6192862016-09-10 13:42:30 -0700424 }
425
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100426 private void onChildAdded(WindowContainer child) {
427 mTreeWeight += child.mTreeWeight;
428 WindowContainer parent = getParent();
429 while (parent != null) {
430 parent.mTreeWeight += child.mTreeWeight;
431 parent = parent.getParent();
432 }
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200433 onChildPositionChanged(child);
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100434 }
435
Wale Ogunwalef6192862016-09-10 13:42:30 -0700436 /**
437 * Removes the input child container from this container which is its parent.
438 *
439 * @return True if the container did contain the input child and it was detached.
440 */
441 @CallSuper
442 void removeChild(E child) {
443 if (mChildren.remove(child)) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100444 onChildRemoved(child);
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700445 if (!child.mReparenting) {
446 child.setParent(null);
447 }
Wale Ogunwalef6192862016-09-10 13:42:30 -0700448 } else {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700449 throw new IllegalArgumentException("removeChild: container=" + child.getName()
450 + " is not a child of container=" + getName());
Wale Ogunwalef6192862016-09-10 13:42:30 -0700451 }
452 }
453
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100454 private void onChildRemoved(WindowContainer child) {
455 mTreeWeight -= child.mTreeWeight;
456 WindowContainer parent = getParent();
457 while (parent != null) {
458 parent.mTreeWeight -= child.mTreeWeight;
459 parent = parent.getParent();
460 }
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200461 onChildPositionChanged(child);
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100462 }
463
Wale Ogunwale571771c2016-08-26 13:18:50 -0700464 /**
465 * Removes this window container and its children with no regard for what else might be going on
466 * in the system. For example, the container will be removed during animation if this method is
467 * called which isn't desirable. For most cases you want to call {@link #removeIfPossible()}
468 * which allows the system to defer removal until a suitable time.
469 */
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700470 @CallSuper
Wale Ogunwale571771c2016-08-26 13:18:50 -0700471 void removeImmediately() {
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700472 while (!mChildren.isEmpty()) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100473 final E child = mChildren.peekLast();
Wale Ogunwale571771c2016-08-26 13:18:50 -0700474 child.removeImmediately();
475 // Need to do this after calling remove on the child because the child might try to
476 // remove/detach itself from its parent which will cause an exception if we remove
477 // it before calling remove on the child.
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100478 if (mChildren.remove(child)) {
479 onChildRemoved(child);
480 }
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700481 }
482
Robert Carrb1579c82017-09-05 14:54:47 -0700483 if (mSurfaceControl != null) {
Tiger Huanged6794e2019-05-07 20:07:59 +0800484 getPendingTransaction().remove(mSurfaceControl);
chaviw6728e2f2018-03-19 15:58:04 -0700485
486 // Merge to parent transaction to ensure the transactions on this WindowContainer are
487 // applied in native even if WindowContainer is removed.
488 if (mParent != null) {
Tiger Huanged6794e2019-05-07 20:07:59 +0800489 mParent.getPendingTransaction().merge(getPendingTransaction());
chaviw6728e2f2018-03-19 15:58:04 -0700490 }
491
Robert Carrb1579c82017-09-05 14:54:47 -0700492 mSurfaceControl = null;
Garfield Tan265ab91a2019-11-12 16:30:49 -0800493 mLastSurfacePosition.set(0, 0);
Chavi Weingartenb736e322018-02-23 00:27:54 +0000494 scheduleAnimation();
Robert Carrb1579c82017-09-05 14:54:47 -0700495 }
496
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700497 if (mParent != null) {
Wale Ogunwalef6192862016-09-10 13:42:30 -0700498 mParent.removeChild(this);
Wale Ogunwale571771c2016-08-26 13:18:50 -0700499 }
500 }
501
502 /**
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100503 * @return The index of this element in the hierarchy tree in prefix order.
504 */
505 int getPrefixOrderIndex() {
506 if (mParent == null) {
507 return 0;
508 }
509 return mParent.getPrefixOrderIndex(this);
510 }
511
512 private int getPrefixOrderIndex(WindowContainer child) {
513 int order = 0;
514 for (int i = 0; i < mChildren.size(); i++) {
515 final WindowContainer childI = mChildren.get(i);
516 if (child == childI) {
517 break;
518 }
519 order += childI.mTreeWeight;
520 }
521 if (mParent != null) {
522 order += mParent.getPrefixOrderIndex(this);
523 }
524
525 // We also need to count ourselves.
526 order++;
527 return order;
528 }
529
530 /**
Wale Ogunwale571771c2016-08-26 13:18:50 -0700531 * Removes this window container and its children taking care not to remove them during a
532 * critical stage in the system. For example, some containers will not be removed during
533 * animation if this method is called.
534 */
535 // TODO: figure-out implementation that works best for this.
536 // E.g. when do we remove from parent list? maybe not...
537 void removeIfPossible() {
538 for (int i = mChildren.size() - 1; i >= 0; --i) {
539 final WindowContainer wc = mChildren.get(i);
540 wc.removeIfPossible();
541 }
542 }
543
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700544 /** Returns true if this window container has the input child. */
Winson Chunge2d72172018-01-25 17:46:20 +0000545 boolean hasChild(E child) {
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700546 for (int i = mChildren.size() - 1; i >= 0; --i) {
Winson Chunge2d72172018-01-25 17:46:20 +0000547 final E current = mChildren.get(i);
Wale Ogunwaled63594a2016-07-18 07:48:30 -0700548 if (current == child || current.hasChild(child)) {
549 return true;
550 }
551 }
552 return false;
553 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700554
Andrii Kulian441e4492016-09-29 15:25:00 -0700555 /**
Andrii Kuliand2765632016-12-12 22:26:34 -0800556 * Move a child from it's current place in siblings list to the specified position,
557 * with an option to move all its parents to top.
558 * @param position Target position to move the child to.
559 * @param child Child to move to selected position.
560 * @param includingParents Flag indicating whether we need to move the entire branch of the
561 * hierarchy when we're moving a child to {@link #POSITION_TOP} or
562 * {@link #POSITION_BOTTOM}. When moving to other intermediate positions
563 * this flag will do nothing.
564 */
565 @CallSuper
566 void positionChildAt(int position, E child, boolean includingParents) {
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800567
568 if (child.getParent() != this) {
569 throw new IllegalArgumentException("removeChild: container=" + child.getName()
570 + " is not a child of container=" + getName()
571 + " current parent=" + child.getParent());
572 }
573
Wale Ogunwalec5cc3012017-01-13 13:26:16 -0800574 if (position >= mChildren.size() - 1) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800575 position = POSITION_TOP;
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700576 } else if (position <= 0) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800577 position = POSITION_BOTTOM;
578 }
579
580 switch (position) {
581 case POSITION_TOP:
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800582 if (mChildren.peekLast() != child) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800583 mChildren.remove(child);
Jorim Jaggi612bb882017-05-16 17:11:18 +0200584 mChildren.add(child);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200585 onChildPositionChanged(child);
Andrii Kuliand2765632016-12-12 22:26:34 -0800586 }
587 if (includingParents && getParent() != null) {
588 getParent().positionChildAt(POSITION_TOP, this /* child */,
589 true /* includingParents */);
590 }
591 break;
592 case POSITION_BOTTOM:
Wale Ogunwalee1fe7fa22016-12-15 18:27:00 -0800593 if (mChildren.peekFirst() != child) {
Andrii Kuliand2765632016-12-12 22:26:34 -0800594 mChildren.remove(child);
595 mChildren.addFirst(child);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200596 onChildPositionChanged(child);
Andrii Kuliand2765632016-12-12 22:26:34 -0800597 }
598 if (includingParents && getParent() != null) {
599 getParent().positionChildAt(POSITION_BOTTOM, this /* child */,
600 true /* includingParents */);
601 }
602 break;
603 default:
Winson Chung123e07a2018-02-27 11:47:16 -0800604 // TODO: Removing the child before reinserting requires the caller to provide a
605 // position that takes into account the removed child (if the index of the
606 // child < position, then the position should be adjusted). We should consider
607 // doing this adjustment here and remove any adjustments in the callers.
Andrii Kuliand2765632016-12-12 22:26:34 -0800608 mChildren.remove(child);
609 mChildren.add(position, child);
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200610 onChildPositionChanged(child);
Andrii Kuliand2765632016-12-12 22:26:34 -0800611 }
612 }
613
614 /**
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800615 * Notify that a child's position has changed. Possible changes are adding or removing a child.
616 */
Wale Ogunwale2322bed2019-10-10 17:24:19 +0200617 void onChildPositionChanged(WindowContainer child) { }
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800618
619 /**
Andrii Kulian441e4492016-09-29 15:25:00 -0700620 * Update override configuration and recalculate full config.
Evan Roskydfe3da72018-10-26 17:21:06 -0700621 * @see #mRequestedOverrideConfiguration
Andrii Kulian441e4492016-09-29 15:25:00 -0700622 * @see #mFullConfiguration
623 */
Wale Ogunwale98d62312017-07-12 09:24:56 -0700624 @Override
Evan Roskydfe3da72018-10-26 17:21:06 -0700625 public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800626 // We must diff before the configuration is applied so that we can capture the change
627 // against the existing bounds.
Evan Roskydfe3da72018-10-26 17:21:06 -0700628 final int diff = diffRequestedOverrideBounds(
629 overrideConfiguration.windowConfiguration.getBounds());
630 super.onRequestedOverrideConfigurationChanged(overrideConfiguration);
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700631 if (mParent != null) {
632 mParent.onDescendantOverrideConfigurationChanged();
633 }
Bryce Leef3c6a472017-11-14 14:53:06 -0800634
635 if (diff == BOUNDS_CHANGE_NONE) {
636 return;
637 }
638
639 if ((diff & BOUNDS_CHANGE_SIZE) == BOUNDS_CHANGE_SIZE) {
640 onResize();
641 } else {
642 onMovedByResize();
643 }
Wale Ogunwale55ddf8f2017-03-20 08:56:38 -0700644 }
645
646 /**
647 * Notify that a descendant's overrideConfiguration has changed.
648 */
649 void onDescendantOverrideConfigurationChanged() {
650 if (mParent != null) {
651 mParent.onDescendantOverrideConfigurationChanged();
652 }
Andrii Kulian441e4492016-09-29 15:25:00 -0700653 }
654
655 /**
Garfield Tan2f145f22018-11-01 15:27:03 -0700656 * Notify that the display this container is on has changed. This could be either this container
657 * is moved to a new display, or some configurations on the display it is on changes.
658 *
659 * @param dc The display this container is on after changes.
Wale Ogunwale02319a62016-09-26 15:21:22 -0700660 */
661 void onDisplayChanged(DisplayContent dc) {
Tiger Huanged6794e2019-05-07 20:07:59 +0800662 mDisplayContent = dc;
663 if (dc != null && dc != this) {
664 dc.getPendingTransaction().merge(mPendingTransaction);
665 }
Wale Ogunwale02319a62016-09-26 15:21:22 -0700666 for (int i = mChildren.size() - 1; i >= 0; --i) {
667 final WindowContainer child = mChildren.get(i);
668 child.onDisplayChanged(dc);
669 }
670 }
671
Tiger Huanged6794e2019-05-07 20:07:59 +0800672 DisplayContent getDisplayContent() {
673 return mDisplayContent;
674 }
675
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700676 void setWaitingForDrawnIfResizingChanged() {
677 for (int i = mChildren.size() - 1; i >= 0; --i) {
678 final WindowContainer wc = mChildren.get(i);
679 wc.setWaitingForDrawnIfResizingChanged();
680 }
681 }
682
683 void onResize() {
684 for (int i = mChildren.size() - 1; i >= 0; --i) {
685 final WindowContainer wc = mChildren.get(i);
Bryce Leed92ae482018-01-22 13:56:23 -0800686 wc.onParentResize();
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700687 }
688 }
689
Bryce Leed92ae482018-01-22 13:56:23 -0800690 void onParentResize() {
691 // In the case this container has specified its own bounds, a parent resize will not
692 // affect its bounds. Any relevant changes will be propagated through changes to the
693 // Configuration override.
694 if (hasOverrideBounds()) {
695 return;
696 }
697
698 // Default implementation is to treat as resize on self.
699 onResize();
700 }
701
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700702 void onMovedByResize() {
703 for (int i = mChildren.size() - 1; i >= 0; --i) {
704 final WindowContainer wc = mChildren.get(i);
705 wc.onMovedByResize();
706 }
707 }
708
709 void resetDragResizingChangeReported() {
710 for (int i = mChildren.size() - 1; i >= 0; --i) {
711 final WindowContainer wc = mChildren.get(i);
712 wc.resetDragResizingChangeReported();
713 }
714 }
715
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700716 void forceWindowsScaleableInTransaction(boolean force) {
717 for (int i = mChildren.size() - 1; i >= 0; --i) {
718 final WindowContainer wc = mChildren.get(i);
719 wc.forceWindowsScaleableInTransaction(force);
720 }
721 }
722
Jorim Jaggia5e10572017-11-15 14:36:26 +0100723 /**
lumark9bca6b42019-10-17 18:35:22 +0800724 * @return {@code true} when this container or its related containers are running an
725 * animation, {@code false} otherwise.
726 *
727 * By default this predicate only checks if this container itself is actually running an
728 * animation, but you can extend the check target over its relatives, or relax the condition
729 * so that this can return {@code true} if an animation starts soon by giving a combination
730 * of {@link #AnimationFlags}.
731 *
732 * Note that you can give a combination of bitmask flags to specify targets and condition for
733 * checking animating status.
734 * e.g. {@code isAnimating(TRANSITION | PARENT)} returns {@code true} if either this
735 * container itself or one of its parents is running an animation or waiting for an app
736 * transition.
737 *
738 * Note that TRANSITION propagates to parents and children as well.
739 *
740 * {@see AnimationFlags#TRANSITION}
741 * {@see AnimationFlags#PARENTS}
742 * {@see AnimationFlags#CHILDREN}
Jorim Jaggia5e10572017-11-15 14:36:26 +0100743 */
lumark9bca6b42019-10-17 18:35:22 +0800744 final boolean isAnimating(int flags) {
745 if (mSurfaceAnimator.isAnimating()) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100746 return true;
747 }
lumark9bca6b42019-10-17 18:35:22 +0800748 if ((flags & TRANSITION) != 0 && isWaitingForTransitionStart()) {
749 return true;
750 }
751 if ((flags & PARENTS) != 0) {
752 final WindowContainer parent = getParent();
753 if (parent != null && parent.isAnimating(flags & ~CHILDREN)) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700754 return true;
755 }
756 }
lumark9bca6b42019-10-17 18:35:22 +0800757 if ((flags & CHILDREN) != 0) {
758 for (int i = 0; i < mChildren.size(); ++i) {
759 final WindowContainer wc = mChildren.get(i);
760 if (wc.isAnimating(flags & ~PARENTS)) {
761 return true;
762 }
763 }
764 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700765 return false;
766 }
767
Jorim Jaggia5e10572017-11-15 14:36:26 +0100768 /**
lumark9bca6b42019-10-17 18:35:22 +0800769 * @return {@code true} when the container is waiting the app transition start, {@code false}
770 * otherwise.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100771 */
lumark9bca6b42019-10-17 18:35:22 +0800772 boolean isWaitingForTransitionStart() {
773 return false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100774 }
775
776 /**
lumark9bca6b42019-10-17 18:35:22 +0800777 * @return {@code true} if in this subtree of the hierarchy we have an
778 * {@ode ActivityRecord#isAnimating(TRANSITION)}, {@code false} otherwise.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200779 */
lumark9bca6b42019-10-17 18:35:22 +0800780 boolean isAppTransitioning() {
781 return forAllActivities(app -> app.isAnimating(TRANSITION));
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200782 }
783
784 /**
Jorim Jaggia5e10572017-11-15 14:36:26 +0100785 * @return Whether our own container running an animation at the moment.
786 */
lumark9bca6b42019-10-17 18:35:22 +0800787 final boolean isAnimating() {
788 return isAnimating(0 /* self only */);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100789 }
790
lumark19a5d2e2019-10-11 16:19:30 +0800791 /**
792 * @return {@code true} if the container is in changing app transition.
793 */
794 boolean isChangingAppTransition() {
795 return false;
796 }
797
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700798 void sendAppVisibilityToClients() {
799 for (int i = mChildren.size() - 1; i >= 0; --i) {
800 final WindowContainer wc = mChildren.get(i);
801 wc.sendAppVisibilityToClients();
802 }
803 }
804
Wale Ogunwale44f21802016-09-02 12:49:48 -0700805 /**
806 * Returns true if the container or one of its children as some content it can display or wants
807 * to display (e.g. app views or saved surface).
808 *
809 * NOTE: While this method will return true if the there is some content to display, it doesn't
810 * mean the container is visible. Use {@link #isVisible()} to determine if the container is
811 * visible.
812 */
813 boolean hasContentToDisplay() {
814 for (int i = mChildren.size() - 1; i >= 0; --i) {
815 final WindowContainer wc = mChildren.get(i);
816 if (wc.hasContentToDisplay()) {
817 return true;
818 }
819 }
820 return false;
821 }
822
823 /**
824 * Returns true if the container or one of its children is considered visible from the
825 * WindowManager perspective which usually means valid surface and some other internal state
826 * are true.
827 *
828 * NOTE: While this method will return true if the surface is visible, it doesn't mean the
829 * client has actually displayed any content. Use {@link #hasContentToDisplay()} to determine if
830 * the container has any content to display.
831 */
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700832 boolean isVisible() {
Wale Ogunwalef6192862016-09-10 13:42:30 -0700833 // TODO: Will this be more correct if it checks the visibility of its parents?
834 // It depends...For example, Tasks and Stacks are only visible if there children are visible
835 // but, WindowState are not visible if there parent are not visible. Maybe have the
Andrii Kuliancd5dcb8b2017-01-03 17:09:45 -0800836 // container specify which direction to traverse for visibility?
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700837 for (int i = mChildren.size() - 1; i >= 0; --i) {
838 final WindowContainer wc = mChildren.get(i);
839 if (wc.isVisible()) {
840 return true;
841 }
842 }
843 return false;
844 }
845
Bryce Lee00d586d2017-07-28 20:48:43 -0700846 /**
Robert Carrb1579c82017-09-05 14:54:47 -0700847 * @return Whether this child is on top of the window hierarchy.
Bryce Lee00d586d2017-07-28 20:48:43 -0700848 */
849 boolean isOnTop() {
850 return getParent().getTopChild() == this && getParent().isOnTop();
851 }
852
Jorim Jaggi10abe2f2017-01-03 16:44:46 +0100853 /** Returns the top child container. */
854 E getTopChild() {
855 return mChildren.peekLast();
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700856 }
Wale Ogunwale51362492016-09-08 17:49:17 -0700857
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700858 /** Returns true if there is still a removal being deferred */
859 boolean checkCompleteDeferredRemoval() {
860 boolean stillDeferringRemoval = false;
861
862 for (int i = mChildren.size() - 1; i >= 0; --i) {
863 final WindowContainer wc = mChildren.get(i);
864 stillDeferringRemoval |= wc.checkCompleteDeferredRemoval();
865 }
866
867 return stillDeferringRemoval;
868 }
869
870 /** Checks if all windows in an app are all drawn and shows them if needed. */
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700871 void checkAppWindowsReadyToShow() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700872 for (int i = mChildren.size() - 1; i >= 0; --i) {
873 final WindowContainer wc = mChildren.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700874 wc.checkAppWindowsReadyToShow();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700875 }
876 }
877
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700878 void onAppTransitionDone() {
879 for (int i = mChildren.size() - 1; i >= 0; --i) {
880 final WindowContainer wc = mChildren.get(i);
881 wc.onAppTransitionDone();
882 }
883 }
884
Garfield Tan90b04282018-12-11 14:04:42 -0800885 /**
886 * Called when this container or one of its descendants changed its requested orientation, and
887 * wants this container to handle it or pass it to its parent.
888 *
889 * @param freezeDisplayToken freeze this app window token if display needs to freeze
890 * @param requestingContainer the container which orientation request has changed
891 * @return {@code true} if handled; {@code false} otherwise.
892 */
893 boolean onDescendantOrientationChanged(@Nullable IBinder freezeDisplayToken,
894 @Nullable ConfigurationContainer requestingContainer) {
895 final WindowContainer parent = getParent();
896 if (parent == null) {
897 return false;
898 }
899 return parent.onDescendantOrientationChanged(freezeDisplayToken,
900 requestingContainer);
901 }
902
903 /**
Garfield Tan49dae102019-02-04 09:51:59 -0800904 * Check if this container or its parent will handle orientation changes from descendants. It's
905 * different from the return value of {@link #onDescendantOrientationChanged(IBinder,
906 * ConfigurationContainer)} in the sense that the return value of this method tells if this
907 * container or its parent will handle the request eventually, while the return value of the
908 * other method is if it handled the request synchronously.
909 *
910 * @return {@code true} if it handles or will handle orientation change in the future; {@code
911 * false} if it won't handle the change at anytime.
912 */
913 boolean handlesOrientationChangeFromDescendant() {
914 final WindowContainer parent = getParent();
915 return parent != null && parent.handlesOrientationChangeFromDescendant();
916 }
917
918 /**
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800919 * Get the configuration orientation by the requested screen orientation
920 * ({@link ActivityInfo.ScreenOrientation}) of this activity.
921 *
922 * @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
923 * {@link Configuration#ORIENTATION_PORTRAIT},
924 * {@link Configuration#ORIENTATION_UNDEFINED}).
925 */
926 int getRequestedConfigurationOrientation() {
927 if (mOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
928 // NOSENSOR means the display's "natural" orientation, so return that.
929 if (mDisplayContent != null) {
930 return mDisplayContent.getNaturalOrientation();
931 }
932 } else if (mOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
933 // LOCKED means the activity's orientation remains unchanged, so return existing value.
934 return getConfiguration().orientation;
935 } else if (isFixedOrientationLandscape(mOrientation)) {
936 return ORIENTATION_LANDSCAPE;
937 } else if (isFixedOrientationPortrait(mOrientation)) {
938 return ORIENTATION_PORTRAIT;
939 }
940 return ORIENTATION_UNDEFINED;
941 }
942
943 /**
Garfield Tan90b04282018-12-11 14:04:42 -0800944 * Calls {@link #setOrientation(int, IBinder, ActivityRecord)} with {@code null} to the last 2
945 * parameters.
946 *
947 * @param orientation the specified orientation.
948 */
Wale Ogunwale51362492016-09-08 17:49:17 -0700949 void setOrientation(int orientation) {
Garfield Tan90b04282018-12-11 14:04:42 -0800950 setOrientation(orientation, null /* freezeDisplayToken */,
951 null /* ActivityRecord */);
952 }
953
954 /**
955 * Sets the specified orientation of this container. It percolates this change upward along the
956 * hierarchy to let each level of the hierarchy a chance to respond to it.
957 *
958 * @param orientation the specified orientation. Needs to be one of {@link
959 * android.content.pm.ActivityInfo.ScreenOrientation}.
960 * @param freezeDisplayToken uses this token to freeze display if orientation change is not
961 * done. Display will not be frozen if this is {@code null}, which
962 * should only happen in tests.
963 * @param requestingContainer the container which orientation request has changed. Mostly used
964 * to ensure it gets correct configuration.
965 */
966 void setOrientation(int orientation, @Nullable IBinder freezeDisplayToken,
967 @Nullable ConfigurationContainer requestingContainer) {
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700968 if (mOrientation == orientation) {
Garfield Tan90b04282018-12-11 14:04:42 -0800969 return;
970 }
Wale Ogunwale8a1860a2019-06-05 08:57:19 -0700971
972 mOrientation = orientation;
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800973 final int configOrientation = getRequestedConfigurationOrientation();
974 if (getRequestedOverrideConfiguration().orientation != configOrientation) {
975 mTmpConfig.setTo(getRequestedOverrideConfiguration());
976 mTmpConfig.orientation = configOrientation;
977 onRequestedOverrideConfigurationChanged(mTmpConfig);
978 }
979
Garfield Tan90b04282018-12-11 14:04:42 -0800980 final WindowContainer parent = getParent();
981 if (parent != null) {
982 onDescendantOrientationChanged(freezeDisplayToken, requestingContainer);
983 }
Wale Ogunwale51362492016-09-08 17:49:17 -0700984 }
985
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700986 int getOrientation() {
987 return getOrientation(mOrientation);
988 }
989
Wale Ogunwale51362492016-09-08 17:49:17 -0700990 /**
991 * Returns the specified orientation for this window container or one of its children is there
992 * is one set, or {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSET} if no
993 * specification is set.
994 * NOTE: {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED} is a
995 * specification...
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -0700996 *
997 * @param candidate The current orientation candidate that will be returned if we don't find a
998 * better match.
999 * @return The orientation as specified by this branch or the window hierarchy.
Wale Ogunwale51362492016-09-08 17:49:17 -07001000 */
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001001 int getOrientation(int candidate) {
Bryce Leea163b762017-01-24 11:05:01 -08001002 if (!fillsParent()) {
1003 // Ignore containers that don't completely fill their parents.
Wale Ogunwale51362492016-09-08 17:49:17 -07001004 return SCREEN_ORIENTATION_UNSET;
1005 }
1006
Bryce Leea163b762017-01-24 11:05:01 -08001007 // The container fills its parent so we can use it orientation if it has one
1008 // specified; otherwise we prefer to use the orientation of its topmost child that has one
Wale Ogunwale51362492016-09-08 17:49:17 -07001009 // specified and fall back on this container's unset or unspecified value as a candidate
1010 // if none of the children have a better candidate for the orientation.
1011 if (mOrientation != SCREEN_ORIENTATION_UNSET
1012 && mOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
1013 return mOrientation;
1014 }
Wale Ogunwale51362492016-09-08 17:49:17 -07001015
1016 for (int i = mChildren.size() - 1; i >= 0; --i) {
1017 final WindowContainer wc = mChildren.get(i);
1018
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001019 // TODO: Maybe mOrientation should default to SCREEN_ORIENTATION_UNSET vs.
1020 // SCREEN_ORIENTATION_UNSPECIFIED?
1021 final int orientation = wc.getOrientation(candidate == SCREEN_ORIENTATION_BEHIND
1022 ? SCREEN_ORIENTATION_BEHIND : SCREEN_ORIENTATION_UNSET);
Wale Ogunwale51362492016-09-08 17:49:17 -07001023 if (orientation == SCREEN_ORIENTATION_BEHIND) {
1024 // container wants us to use the orientation of the container behind it. See if we
1025 // can find one. Else return SCREEN_ORIENTATION_BEHIND so the caller can choose to
1026 // look behind this container.
1027 candidate = orientation;
1028 continue;
1029 }
1030
1031 if (orientation == SCREEN_ORIENTATION_UNSET) {
1032 continue;
1033 }
1034
1035 if (wc.fillsParent() || orientation != SCREEN_ORIENTATION_UNSPECIFIED) {
1036 // Use the orientation if the container fills its parent or requested an explicit
1037 // orientation that isn't SCREEN_ORIENTATION_UNSPECIFIED.
1038 return orientation;
1039 }
1040 }
1041
1042 return candidate;
1043 }
1044
1045 /**
1046 * Returns true if this container is opaque and fills all the space made available by its parent
1047 * container.
1048 *
1049 * NOTE: It is possible for this container to occupy more space than the parent has (or less),
1050 * this is just a signal from the client to window manager stating its intent, but not what it
1051 * actually does.
1052 */
1053 boolean fillsParent() {
1054 return false;
1055 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001056
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001057 // TODO: Users would have their own window containers under the display container?
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001058 void switchUser(int userId) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001059 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -07001060 mChildren.get(i).switchUser(userId);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001061 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001062 }
1063
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001064 /**
1065 * For all windows at or below this container call the callback.
1066 * @param callback Calls the {@link ToBooleanFunction#apply} method for each window found and
1067 * stops the search if {@link ToBooleanFunction#apply} returns true.
1068 * @param traverseTopToBottom If true traverses the hierarchy from top-to-bottom in terms of
1069 * z-order, else from bottom-to-top.
1070 * @return True if the search ended before we reached the end of the hierarchy due to
Wale Ogunwale1e129a42016-11-21 13:03:47 -08001071 * {@link ToBooleanFunction#apply} returning true.
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001072 */
1073 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001074 if (traverseTopToBottom) {
1075 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001076 if (mChildren.get(i).forAllWindows(callback, traverseTopToBottom)) {
1077 return true;
1078 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001079 }
1080 } else {
1081 final int count = mChildren.size();
1082 for (int i = 0; i < count; i++) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001083 if (mChildren.get(i).forAllWindows(callback, traverseTopToBottom)) {
1084 return true;
1085 }
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001086 }
1087 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001088 return false;
1089 }
1090
1091 void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleee41d4a2016-11-21 08:41:10 -08001092 ForAllWindowsConsumerWrapper wrapper = obtainConsumerWrapper(callback);
1093 forAllWindows(wrapper, traverseTopToBottom);
1094 wrapper.release();
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001095 }
1096
lumark9bca6b42019-10-17 18:35:22 +08001097 boolean forAllActivities(ToBooleanFunction<ActivityRecord> callback) {
lumark588a3e82018-07-20 18:53:54 +08001098 for (int i = mChildren.size() - 1; i >= 0; --i) {
lumark9bca6b42019-10-17 18:35:22 +08001099 if (mChildren.get(i).forAllActivities(callback)) {
1100 return true;
1101 }
lumark588a3e82018-07-20 18:53:54 +08001102 }
lumark9bca6b42019-10-17 18:35:22 +08001103 return false;
lumark588a3e82018-07-20 18:53:54 +08001104 }
1105
Winson Chungd5852192019-09-06 17:20:28 -07001106 void forAllWallpaperWindows(Consumer<WallpaperWindowToken> callback) {
1107 for (int i = mChildren.size() - 1; i >= 0; --i) {
1108 mChildren.get(i).forAllWallpaperWindows(callback);
1109 }
1110 }
1111
Jorim Jaggi51304d72017-05-17 17:25:32 +02001112 /**
1113 * For all tasks at or below this container call the callback.
1114 *
1115 * @param callback Callback to be called for every task.
1116 */
1117 void forAllTasks(Consumer<Task> callback) {
1118 for (int i = mChildren.size() - 1; i >= 0; --i) {
1119 mChildren.get(i).forAllTasks(callback);
1120 }
1121 }
1122
lumarkbc0032a2019-11-01 21:38:13 +08001123 /**
1124 * For all tasks at or below this container call the callback.
1125 *
1126 * @param callback Calls the {@link ToBooleanFunction#apply} method for each task found and
1127 * stops the search if {@link ToBooleanFunction#apply} returns {@code true}.
1128 */
1129 boolean forAllTasks(ToBooleanFunction<Task> callback) {
1130 for (int i = mChildren.size() - 1; i >= 0; --i) {
1131 if (mChildren.get(i).forAllTasks(callback)) {
1132 return true;
1133 }
1134 }
1135 return false;
1136 }
1137
Wale Ogunwaled1880962016-11-08 10:31:59 -08001138 WindowState getWindow(Predicate<WindowState> callback) {
1139 for (int i = mChildren.size() - 1; i >= 0; --i) {
1140 final WindowState w = mChildren.get(i).getWindow(callback);
1141 if (w != null) {
1142 return w;
1143 }
1144 }
1145
1146 return null;
1147 }
1148
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001149 /**
Wale Ogunwalef6192862016-09-10 13:42:30 -07001150 * Returns 1, 0, or -1 depending on if this container is greater than, equal to, or lesser than
1151 * the input container in terms of z-order.
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001152 */
1153 @Override
1154 public int compareTo(WindowContainer other) {
1155 if (this == other) {
1156 return 0;
1157 }
1158
1159 if (mParent != null && mParent == other.mParent) {
Jorim Jaggi612bb882017-05-16 17:11:18 +02001160 final WindowList<WindowContainer> list = mParent.mChildren;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001161 return list.indexOf(this) > list.indexOf(other) ? 1 : -1;
1162 }
1163
1164 final LinkedList<WindowContainer> thisParentChain = mTmpChain1;
1165 final LinkedList<WindowContainer> otherParentChain = mTmpChain2;
Jorim Jaggi4448e1e2017-05-16 22:26:02 +02001166 try {
1167 getParents(thisParentChain);
1168 other.getParents(otherParentChain);
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001169
Jorim Jaggi4448e1e2017-05-16 22:26:02 +02001170 // Find the common ancestor of both containers.
1171 WindowContainer commonAncestor = null;
1172 WindowContainer thisTop = thisParentChain.peekLast();
1173 WindowContainer otherTop = otherParentChain.peekLast();
1174 while (thisTop != null && otherTop != null && thisTop == otherTop) {
1175 commonAncestor = thisParentChain.removeLast();
1176 otherParentChain.removeLast();
1177 thisTop = thisParentChain.peekLast();
1178 otherTop = otherParentChain.peekLast();
1179 }
1180
1181 // Containers don't belong to the same hierarchy???
1182 if (commonAncestor == null) {
1183 throw new IllegalArgumentException("No in the same hierarchy this="
1184 + thisParentChain + " other=" + otherParentChain);
1185 }
1186
1187 // Children are always considered greater than their parents, so if one of the containers
1188 // we are comparing it the parent of the other then whichever is the child is greater.
1189 if (commonAncestor == this) {
1190 return -1;
1191 } else if (commonAncestor == other) {
1192 return 1;
1193 }
1194
1195 // The position of the first non-common ancestor in the common ancestor list determines
1196 // which is greater the which.
1197 final WindowList<WindowContainer> list = commonAncestor.mChildren;
1198 return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast())
1199 ? 1 : -1;
1200 } finally {
1201 mTmpChain1.clear();
1202 mTmpChain2.clear();
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001203 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001204 }
1205
1206 private void getParents(LinkedList<WindowContainer> parents) {
1207 parents.clear();
1208 WindowContainer current = this;
1209 do {
1210 parents.addLast(current);
1211 current = current.mParent;
1212 } while (current != null);
1213 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001214
Robert Carrb1579c82017-09-05 14:54:47 -07001215 SurfaceControl.Builder makeSurface() {
1216 final WindowContainer p = getParent();
1217 return p.makeChildSurface(this);
1218 }
1219
Robert Carrf59b8dd2017-10-02 18:58:36 -07001220 /**
1221 * @param child The WindowContainer this child surface is for, or null if the Surface
1222 * is not assosciated with a WindowContainer (e.g. a surface used for Dimming).
1223 */
Robert Carrb1579c82017-09-05 14:54:47 -07001224 SurfaceControl.Builder makeChildSurface(WindowContainer child) {
1225 final WindowContainer p = getParent();
1226 // Give the parent a chance to set properties. In hierarchy v1 we rely
1227 // on this to set full-screen dimensions on all our Surface-less Layers.
Robert Carree4d4b92017-11-22 12:21:46 -08001228 return p.makeChildSurface(child)
1229 .setParent(mSurfaceControl);
Robert Carrb1579c82017-09-05 14:54:47 -07001230 }
Robert Carrdea7bf42019-04-04 12:02:51 -07001231 /*
1232 * @return The SurfaceControl parent for this containers SurfaceControl.
1233 * The SurfaceControl must be valid if non-null.
1234 */
Jorim Jaggia5e10572017-11-15 14:36:26 +01001235 @Override
1236 public SurfaceControl getParentSurfaceControl() {
1237 final WindowContainer parent = getParent();
1238 if (parent == null) {
1239 return null;
1240 }
1241 return parent.getSurfaceControl();
1242 }
1243
Robert Carrb1579c82017-09-05 14:54:47 -07001244 /**
1245 * @return Whether this WindowContainer should be magnified by the accessibility magnifier.
1246 */
1247 boolean shouldMagnify() {
Yuki Awano4c36b552018-04-24 17:27:50 +09001248 if (mSurfaceControl == null) {
1249 return false;
1250 }
1251
Robert Carrb1579c82017-09-05 14:54:47 -07001252 for (int i = 0; i < mChildren.size(); i++) {
1253 if (!mChildren.get(i).shouldMagnify()) {
1254 return false;
1255 }
1256 }
1257 return true;
1258 }
1259
1260 SurfaceSession getSession() {
1261 if (getParent() != null) {
1262 return getParent().getSession();
1263 }
1264 return null;
1265 }
1266
1267 void assignLayer(Transaction t, int layer) {
Jorim Jaggiffe128d2017-11-30 13:54:36 +01001268 final boolean changed = layer != mLastLayer || mLastRelativeToLayer != null;
1269 if (mSurfaceControl != null && changed) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001270 setLayer(t, layer);
Jorim Jaggiffe128d2017-11-30 13:54:36 +01001271 mLastLayer = layer;
1272 mLastRelativeToLayer = null;
1273 }
1274 }
1275
1276 void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
1277 final boolean changed = layer != mLastLayer || mLastRelativeToLayer != relativeTo;
1278 if (mSurfaceControl != null && changed) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001279 setRelativeLayer(t, relativeTo, layer);
Jorim Jaggiffe128d2017-11-30 13:54:36 +01001280 mLastLayer = layer;
1281 mLastRelativeToLayer = relativeTo;
Robert Carrb1579c82017-09-05 14:54:47 -07001282 }
1283 }
1284
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001285 protected void setLayer(Transaction t, int layer) {
1286
1287 // Route through surface animator to accommodate that our surface control might be
1288 // attached to the leash, and leash is attached to parent container.
1289 mSurfaceAnimator.setLayer(t, layer);
1290 }
1291
1292 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
1293
1294 // Route through surface animator to accommodate that our surface control might be
1295 // attached to the leash, and leash is attached to parent container.
1296 mSurfaceAnimator.setRelativeLayer(t, relativeTo, layer);
1297 }
1298
1299 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
1300 mSurfaceAnimator.reparent(t, newParent);
1301 }
1302
Robert Carrb1579c82017-09-05 14:54:47 -07001303 void assignChildLayers(Transaction t) {
1304 int layer = 0;
Robert Carrb1579c82017-09-05 14:54:47 -07001305
1306 // We use two passes as a way to promote children which
1307 // need Z-boosting to the end of the list.
Jorim Jaggiffe128d2017-11-30 13:54:36 +01001308 for (int j = 0; j < mChildren.size(); ++j) {
1309 final WindowContainer wc = mChildren.get(j);
1310 wc.assignChildLayers(t);
1311 if (!wc.needsZBoost()) {
1312 wc.assignLayer(t, layer++);
Robert Carrb1579c82017-09-05 14:54:47 -07001313 }
Jorim Jaggiffe128d2017-11-30 13:54:36 +01001314 }
1315 for (int j = 0; j < mChildren.size(); ++j) {
1316 final WindowContainer wc = mChildren.get(j);
1317 if (wc.needsZBoost()) {
1318 wc.assignLayer(t, layer++);
1319 }
Robert Carrb1579c82017-09-05 14:54:47 -07001320 }
1321 }
1322
1323 void assignChildLayers() {
Robert Carrf59b8dd2017-10-02 18:58:36 -07001324 assignChildLayers(getPendingTransaction());
Jorim Jaggiffe128d2017-11-30 13:54:36 +01001325 scheduleAnimation();
Robert Carrb1579c82017-09-05 14:54:47 -07001326 }
1327
1328 boolean needsZBoost() {
1329 for (int i = 0; i < mChildren.size(); i++) {
1330 if (mChildren.get(i).needsZBoost()) {
1331 return true;
1332 }
1333 }
1334 return false;
1335 }
1336
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001337 /**
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001338 * Write to a protocol buffer output stream. Protocol buffer message definition is at
Yi Jin6c6e9ca2018-03-20 16:53:35 -07001339 * {@link com.android.server.wm.WindowContainerProto}.
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001340 *
Adrian Roos4921ccf2017-09-28 16:54:06 +02001341 * @param proto Stream to write the WindowContainer object to.
1342 * @param fieldId Field Id of the WindowContainer as defined in the parent message.
Nataniel Borges023ecb52019-01-16 14:15:43 -08001343 * @param logLevel Determines the amount of data to be written to the Protobuf.
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001344 * @hide
1345 */
1346 @CallSuper
1347 @Override
Nataniel Borges023ecb52019-01-16 14:15:43 -08001348 public void writeToProto(ProtoOutputStream proto, long fieldId,
1349 @WindowTraceLogLevel int logLevel) {
1350 boolean isVisible = isVisible();
1351 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible) {
1352 return;
1353 }
1354
Adrian Roos4921ccf2017-09-28 16:54:06 +02001355 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -08001356 super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
Adrian Roos4921ccf2017-09-28 16:54:06 +02001357 proto.write(ORIENTATION, mOrientation);
Nataniel Borges023ecb52019-01-16 14:15:43 -08001358 proto.write(VISIBLE, isVisible);
1359 if (mSurfaceAnimator.isAnimating()) {
1360 mSurfaceAnimator.writeToProto(proto, SURFACE_ANIMATOR);
1361 }
Adrian Roos4921ccf2017-09-28 16:54:06 +02001362 proto.end(token);
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07001363 }
1364
Wale Ogunwaleee41d4a2016-11-21 08:41:10 -08001365 private ForAllWindowsConsumerWrapper obtainConsumerWrapper(Consumer<WindowState> consumer) {
1366 ForAllWindowsConsumerWrapper wrapper = mConsumerWrapperPool.acquire();
1367 if (wrapper == null) {
1368 wrapper = new ForAllWindowsConsumerWrapper();
1369 }
1370 wrapper.setConsumer(consumer);
1371 return wrapper;
1372 }
1373
1374 private final class ForAllWindowsConsumerWrapper implements ToBooleanFunction<WindowState> {
1375
1376 private Consumer<WindowState> mConsumer;
1377
1378 void setConsumer(Consumer<WindowState> consumer) {
1379 mConsumer = consumer;
1380 }
1381
1382 @Override
1383 public boolean apply(WindowState w) {
1384 mConsumer.accept(w);
1385 return false;
1386 }
1387
1388 void release() {
1389 mConsumer = null;
1390 mConsumerWrapperPool.release(this);
1391 }
1392 }
Robert Carrb1579c82017-09-05 14:54:47 -07001393
1394 // TODO(b/68336570): Should this really be on WindowContainer since it
1395 // can only be used on the top-level nodes that aren't animated?
1396 // (otherwise we would be fighting other callers of setMatrix).
1397 void applyMagnificationSpec(Transaction t, MagnificationSpec spec) {
1398 if (shouldMagnify()) {
1399 t.setMatrix(mSurfaceControl, spec.scale, 0, 0, spec.scale)
1400 .setPosition(mSurfaceControl, spec.offsetX, spec.offsetY);
1401 } else {
1402 for (int i = 0; i < mChildren.size(); i++) {
1403 mChildren.get(i).applyMagnificationSpec(t, spec);
1404 }
1405 }
1406 }
1407
Robert Carrb1579c82017-09-05 14:54:47 -07001408 void prepareSurfaces() {
chaviw7f1fa992018-01-10 13:52:12 -08001409 // If a leash has been set when the transaction was committed, then the leash reparent has
1410 // been committed.
1411 mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
Robert Carrb1579c82017-09-05 14:54:47 -07001412 for (int i = 0; i < mChildren.size(); i++) {
1413 mChildren.get(i).prepareSurfaces();
1414 }
1415 }
1416
1417 /**
chaviw7f1fa992018-01-10 13:52:12 -08001418 * @return true if the reparent to animation leash transaction has been committed, false
1419 * otherwise.
1420 */
1421 boolean hasCommittedReparentToAnimationLeash() {
1422 return mCommittedReparentToAnimationLeash;
1423 }
1424
1425 /**
Tiger Huanged6794e2019-05-07 20:07:59 +08001426 * Trigger a call to prepareSurfaces from the animation thread, such that pending transactions
1427 * will be applied.
Robert Carrb1579c82017-09-05 14:54:47 -07001428 */
1429 void scheduleAnimation() {
1430 if (mParent != null) {
1431 mParent.scheduleAnimation();
1432 }
1433 }
1434
Robert Carrdea7bf42019-04-04 12:02:51 -07001435 /**
1436 * @return The SurfaceControl for this container.
1437 * The SurfaceControl must be valid if non-null.
1438 */
Jorim Jaggia5e10572017-11-15 14:36:26 +01001439 @Override
1440 public SurfaceControl getSurfaceControl() {
Robert Carrb1579c82017-09-05 14:54:47 -07001441 return mSurfaceControl;
1442 }
1443
Jorim Jaggia5e10572017-11-15 14:36:26 +01001444 @Override
1445 public Transaction getPendingTransaction() {
Tiger Huanged6794e2019-05-07 20:07:59 +08001446 final DisplayContent displayContent = getDisplayContent();
1447 if (displayContent != null && displayContent != this) {
1448 return displayContent.getPendingTransaction();
1449 }
1450 // This WindowContainer has not attached to a display yet or this is a DisplayContent, so we
1451 // let the caller to save the surface operations within the local mPendingTransaction.
1452 // If this is not a DisplayContent, we will merge it to the pending transaction of its
1453 // display once it attaches to it.
Robert Carrf59b8dd2017-10-02 18:58:36 -07001454 return mPendingTransaction;
1455 }
Jorim Jaggia5e10572017-11-15 14:36:26 +01001456
1457 /**
1458 * Starts an animation on the container.
1459 *
1460 * @param anim The animation to run.
1461 * @param hidden Whether our container is currently hidden. TODO This should use isVisible at
1462 * some point but the meaning is too weird to work for all containers.
1463 */
1464 void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden) {
1465 if (DEBUG_ANIM) Slog.v(TAG, "Starting animation on " + this + ": " + anim);
1466
1467 // TODO: This should use isVisible() but because isVisible has a really weird meaning at
1468 // the moment this doesn't work for all animatable window containers.
1469 mSurfaceAnimator.startAnimation(t, anim, hidden);
1470 }
1471
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001472 void transferAnimation(WindowContainer from) {
1473 mSurfaceAnimator.transferAnimation(from.mSurfaceAnimator);
1474 }
1475
Jorim Jaggia5e10572017-11-15 14:36:26 +01001476 void cancelAnimation() {
1477 mSurfaceAnimator.cancelAnimation();
1478 }
1479
1480 @Override
1481 public Builder makeAnimationLeash() {
1482 return makeSurface();
1483 }
1484
Jorim Jaggi596a1992017-12-29 14:48:02 +01001485 @Override
1486 public SurfaceControl getAnimationLeashParent() {
1487 return getParentSurfaceControl();
1488 }
1489
chaviw23ee71c2017-12-18 11:29:41 -08001490 /**
1491 * @return The layer on which all app animations are happening.
1492 */
Jorim Jaggi391790622018-04-18 15:30:44 +02001493 SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) {
chaviw23ee71c2017-12-18 11:29:41 -08001494 final WindowContainer parent = getParent();
1495 if (parent != null) {
Jorim Jaggi391790622018-04-18 15:30:44 +02001496 return parent.getAppAnimationLayer(animationLayer);
chaviw23ee71c2017-12-18 11:29:41 -08001497 }
1498 return null;
1499 }
1500
lumark19a5d2e2019-10-11 16:19:30 +08001501 // TODO: Remove this and use #getBounds() instead once we set an app transition animation
1502 // on TaskStack.
1503 Rect getAnimationBounds(int appStackClipMode) {
1504 return getBounds();
1505 }
1506
1507 /**
1508 * Applies the app transition animation according the given the layout properties in the
1509 * window hierarchy.
1510 *
1511 * @param lp The layout parameters of the window.
1512 * @param transit The app transition type indicates what kind of transition to be applied.
1513 * @param enter Whether the app transition is entering transition or not.
1514 * @param isVoiceInteraction Whether the container is participating in voice interaction or not.
1515 *
1516 * @return {@code true} when the container applied the app transition, {@code false} if the
1517 * app transition is disabled or skipped.
1518 *
1519 * @see #getAnimationAdapter
1520 */
1521 boolean applyAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
1522 boolean isVoiceInteraction) {
1523 if (mWmService.mDisableTransitionAnimation) {
1524 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
1525 "applyAnimation: transition animation is disabled or skipped. "
1526 + "container=%s", this);
1527 cancelAnimation();
1528 return false;
1529 }
1530
1531 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
1532 // to animate and it can cause strange artifacts when we unfreeze the display if some
1533 // different animation is running.
1534 try {
1535 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WC#applyAnimation");
1536 if (okToAnimate()) {
lumarkbc0032a2019-11-01 21:38:13 +08001537 final Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp,
1538 transit, enter, isVoiceInteraction);
lumark19a5d2e2019-10-11 16:19:30 +08001539 AnimationAdapter adapter = adapters.first;
1540 AnimationAdapter thumbnailAdapter = adapters.second;
1541 if (adapter != null) {
1542 startAnimation(getPendingTransaction(), adapter, !isVisible());
1543 if (adapter.getShowWallpaper()) {
1544 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1545 }
1546 if (thumbnailAdapter != null) {
1547 mThumbnail.startAnimation(
1548 getPendingTransaction(), thumbnailAdapter, !isVisible());
1549 }
1550 }
1551 } else {
1552 cancelAnimation();
1553 }
1554 } finally {
1555 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
1556 }
1557
1558 return isAnimating();
1559 }
1560
1561 /**
1562 * Gets the {@link AnimationAdapter} according the given window layout properties in the window
1563 * hierarchy.
1564 *
1565 * @return The return value will always contain two elements, one for normal animations and the
1566 * other for thumbnail animation, both can be {@code null}.
1567 *
1568 * @See com.android.server.wm.RemoteAnimationController.RemoteAnimationRecord
1569 * @See LocalAnimationAdapter
1570 */
1571 Pair<AnimationAdapter, AnimationAdapter> getAnimationAdapter(WindowManager.LayoutParams lp,
1572 int transit, boolean enter, boolean isVoiceInteraction) {
1573 final Pair<AnimationAdapter, AnimationAdapter> resultAdapters;
1574 final int appStackClipMode = getDisplayContent().mAppTransition.getAppStackClipMode();
1575
1576 // Separate position and size for use in animators.
1577 mTmpRect.set(getAnimationBounds(appStackClipMode));
1578 mTmpPoint.set(mTmpRect.left, mTmpRect.top);
1579 mTmpRect.offsetTo(0, 0);
1580
1581 final RemoteAnimationController controller =
1582 getDisplayContent().mAppTransition.getRemoteAnimationController();
1583 final boolean isChanging = AppTransition.isChangeTransit(transit) && enter
1584 && isChangingAppTransition();
1585
1586 // Delaying animation start isn't compatible with remote animations at all.
1587 if (controller != null && !mSurfaceAnimator.isAnimationStartDelayed()) {
1588 final RemoteAnimationController.RemoteAnimationRecord adapters =
1589 controller.createRemoteAnimationRecord(this, mTmpPoint, mTmpRect,
1590 (isChanging ? mTransitStartRect : null));
1591 resultAdapters = new Pair<>(adapters.mAdapter, adapters.mThumbnailAdapter);
1592 } else if (isChanging) {
1593 final float durationScale = mWmService.getTransitionAnimationScaleLocked();
1594 final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
1595 mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y);
1596
lumarkbc0032a2019-11-01 21:38:13 +08001597 final AnimationAdapter adapter = new LocalAnimationAdapter(
lumark19a5d2e2019-10-11 16:19:30 +08001598 new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo,
1599 durationScale, true /* isAppAnimation */, false /* isThumbnail */),
1600 getSurfaceAnimationRunner());
1601
lumarkbc0032a2019-11-01 21:38:13 +08001602 final AnimationAdapter thumbnailAdapter = mThumbnail != null
1603 ? new LocalAnimationAdapter(new WindowChangeAnimationSpec(mTransitStartRect,
1604 mTmpRect, displayInfo, durationScale, true /* isAppAnimation */,
1605 true /* isThumbnail */), getSurfaceAnimationRunner())
1606 : null;
lumark19a5d2e2019-10-11 16:19:30 +08001607 resultAdapters = new Pair<>(adapter, thumbnailAdapter);
1608 mTransit = transit;
1609 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
1610 } else {
1611 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
1612 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
1613
1614 if (a != null) {
1615 // Only apply corner radius to animation if we're not in multi window mode.
1616 // We don't want rounded corners when in pip or split screen.
1617 final float windowCornerRadius = !inMultiWindowMode()
1618 ? getDisplayContent().getWindowCornerRadius()
1619 : 0;
1620 AnimationAdapter adapter = new LocalAnimationAdapter(
1621 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
1622 getDisplayContent().mAppTransition.canSkipFirstFrame(),
1623 appStackClipMode, true /* isAppAnimation */, windowCornerRadius),
1624 getSurfaceAnimationRunner());
1625
1626 resultAdapters = new Pair<>(adapter, null);
1627 mNeedsZBoost = a.getZAdjustment() == Animation.ZORDER_TOP;
1628 mTransit = transit;
1629 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
1630 } else {
1631 resultAdapters = new Pair<>(null, null);
1632 }
1633 }
1634 return resultAdapters;
1635 }
1636
1637 final SurfaceAnimationRunner getSurfaceAnimationRunner() {
1638 return mWmService.mSurfaceAnimationRunner;
1639 }
1640
1641 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
1642 boolean isVoiceInteraction) {
1643 final DisplayContent displayContent = getDisplayContent();
1644 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1645 final int width = displayInfo.appWidth;
1646 final int height = displayInfo.appHeight;
1647 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, "applyAnimation: container=%s", this);
1648
1649 // Determine the visible rect to calculate the thumbnail clip with
1650 // getAnimationFrames.
1651 final Rect frame = new Rect(0, 0, width, height);
1652 final Rect displayFrame = new Rect(0, 0,
1653 displayInfo.logicalWidth, displayInfo.logicalHeight);
1654 final Rect insets = new Rect();
1655 final Rect stableInsets = new Rect();
1656 final Rect surfaceInsets = new Rect();
1657 getAnimationFrames(frame, insets, stableInsets, surfaceInsets);
1658
1659 if (mLaunchTaskBehind) {
1660 // Differentiate the two animations. This one which is briefly on the screen
1661 // gets the !enter animation, and the other one which remains on the
1662 // screen gets the enter animation. Both appear in the mOpeningApps set.
1663 enter = false;
1664 }
1665 ProtoLog.d(WM_DEBUG_APP_TRANSITIONS,
1666 "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s "
1667 + "surfaceInsets=%s",
1668 AppTransition.appTransitionToString(transit), enter, frame, insets, surfaceInsets);
1669 final Configuration displayConfig = displayContent.getConfiguration();
1670 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
1671 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
1672 surfaceInsets, stableInsets, isVoiceInteraction, inFreeformWindowingMode(), this);
1673 if (a != null) {
1674 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
1675 final int containingWidth = frame.width();
1676 final int containingHeight = frame.height();
1677 a.initialize(containingWidth, containingHeight, width, height);
1678 a.scaleCurrentDuration(mWmService.getTransitionAnimationScaleLocked());
1679 }
1680 return a;
1681 }
1682
1683 RemoteAnimationTarget createRemoteAnimationTarget(
1684 RemoteAnimationController.RemoteAnimationRecord record) {
1685 return null;
1686 }
1687
1688 boolean okToDisplay() {
1689 return mDisplayContent != null && mDisplayContent.okToDisplay();
1690 }
1691
1692 boolean okToAnimate() {
1693 return mDisplayContent != null && mDisplayContent.okToAnimate();
1694 }
1695
Jorim Jaggia5e10572017-11-15 14:36:26 +01001696 @Override
1697 public void commitPendingTransaction() {
1698 scheduleAnimation();
1699 }
1700
Robert Carr2f8aa392018-01-31 14:46:51 -08001701 void reassignLayer(Transaction t) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001702 final WindowContainer parent = getParent();
1703 if (parent != null) {
1704 parent.assignChildLayers(t);
1705 }
1706 }
1707
1708 @Override
1709 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Robert Carrf12f9d32018-03-01 15:24:36 -08001710 mLastLayer = -1;
Jorim Jaggia5e10572017-11-15 14:36:26 +01001711 reassignLayer(t);
1712 }
1713
1714 @Override
lumarkf6f34942019-04-29 16:56:50 +08001715 public void onAnimationLeashLost(Transaction t) {
Robert Carrf12f9d32018-03-01 15:24:36 -08001716 mLastLayer = -1;
Jorim Jaggia5e10572017-11-15 14:36:26 +01001717 reassignLayer(t);
1718 }
1719
1720 /**
1721 * Called when an animation has finished running.
1722 */
1723 protected void onAnimationFinished() {
chaviwccd5d502019-02-22 13:30:31 -08001724 mWmService.onAnimationFinished();
Jorim Jaggia5e10572017-11-15 14:36:26 +01001725 }
1726
1727 /**
1728 * @return The currently running animation, if any, or {@code null} otherwise.
1729 */
1730 AnimationAdapter getAnimation() {
1731 return mSurfaceAnimator.getAnimation();
1732 }
1733
1734 /**
1735 * @see SurfaceAnimator#startDelayingAnimationStart
1736 */
1737 void startDelayingAnimationStart() {
1738 mSurfaceAnimator.startDelayingAnimationStart();
1739 }
1740
1741 /**
1742 * @see SurfaceAnimator#endDelayingAnimationStart
1743 */
1744 void endDelayingAnimationStart() {
1745 mSurfaceAnimator.endDelayingAnimationStart();
1746 }
1747
1748 @Override
1749 public int getSurfaceWidth() {
1750 return mSurfaceControl.getWidth();
1751 }
1752
1753 @Override
1754 public int getSurfaceHeight() {
1755 return mSurfaceControl.getHeight();
1756 }
1757
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001758 @CallSuper
Jorim Jaggia5e10572017-11-15 14:36:26 +01001759 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1760 if (mSurfaceAnimator.isAnimating()) {
1761 pw.print(prefix); pw.println("ContainerAnimator:");
1762 mSurfaceAnimator.dump(pw, prefix + " ");
1763 }
1764 }
chaviwe07246a2017-12-12 16:18:29 -08001765
chaviw2f0567b2018-01-29 16:22:02 -08001766 void updateSurfacePosition() {
chaviwe07246a2017-12-12 16:18:29 -08001767 if (mSurfaceControl == null) {
1768 return;
1769 }
1770
Evan Roskyed6767f2018-10-26 17:21:06 -07001771 getRelativeDisplayedPosition(mTmpPos);
chaviw3e751af2018-01-11 11:22:39 -08001772 if (mTmpPos.equals(mLastSurfacePosition)) {
1773 return;
1774 }
1775
chaviw2f0567b2018-01-29 16:22:02 -08001776 getPendingTransaction().setPosition(mSurfaceControl, mTmpPos.x, mTmpPos.y);
chaviw3e751af2018-01-11 11:22:39 -08001777 mLastSurfacePosition.set(mTmpPos.x, mTmpPos.y);
chaviwe07246a2017-12-12 16:18:29 -08001778 }
1779
Evan Rosky65dffa62019-02-04 14:09:53 -08001780 @VisibleForTesting
Evan Rosky89f5c1d2019-01-29 10:04:05 -08001781 Point getLastSurfacePosition() {
1782 return mLastSurfacePosition;
1783 }
1784
Evan Roskyed6767f2018-10-26 17:21:06 -07001785 /**
1786 * Displayed bounds specify where to display this container at. It differs from bounds during
1787 * certain operations (like animation or interactive dragging).
1788 *
1789 * @return the bounds to display this container at.
1790 */
1791 Rect getDisplayedBounds() {
1792 return getBounds();
1793 }
1794
lumark19a5d2e2019-10-11 16:19:30 +08001795 /**
1796 * The {@code outFrame} retrieved by this method specifies where the animation will finish
1797 * the entrance animation, as the next frame will display the window at these coordinates. In
1798 * case of exit animation, this is where the animation will start, as the frame before the
1799 * animation is displaying the window at these bounds.
1800 *
1801 * @param outFrame The bounds where entrance animation finishes or exit animation starts.
1802 * @param outInsets Insets that are covered by system windows.
1803 * @param outStableInsets Insets that determine the area covered by the stable system windows.
1804 * @param outSurfaceInsets Positive insets between the drawing surface and window content.
1805 */
1806 void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
1807 Rect outSurfaceInsets) {
1808 final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
1809 outFrame.set(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1810 outInsets.setEmpty();
1811 outStableInsets.setEmpty();
1812 outSurfaceInsets.setEmpty();
1813 }
1814
Evan Roskyed6767f2018-10-26 17:21:06 -07001815 void getRelativeDisplayedPosition(Point outPos) {
1816 final Rect dispBounds = getDisplayedBounds();
1817 outPos.set(dispBounds.left, dispBounds.top);
chaviwe07246a2017-12-12 16:18:29 -08001818 final WindowContainer parent = getParent();
1819 if (parent != null) {
Evan Roskyed6767f2018-10-26 17:21:06 -07001820 final Rect parentBounds = parent.getDisplayedBounds();
chaviwe07246a2017-12-12 16:18:29 -08001821 outPos.offset(-parentBounds.left, -parentBounds.top);
1822 }
1823 }
chaviw2fb06bc2018-01-19 17:09:15 -08001824
Yunfan Chen87b5a242019-10-01 17:53:59 +09001825 void waitForAllWindowsDrawn() {
1826 final WindowManagerPolicy policy = mWmService.mPolicy;
1827 forAllWindows(w -> {
1828 final boolean keyguard = policy.isKeyguardHostWindow(w.mAttrs);
Garfield Tane8d84ab2019-10-11 09:49:40 -07001829 if (w.isVisibleLw() && (w.mActivityRecord != null || keyguard)) {
Yunfan Chen87b5a242019-10-01 17:53:59 +09001830 w.mWinAnimator.mDrawState = DRAW_PENDING;
1831 // Force add to mResizingWindows.
1832 w.resetLastContentInsets();
1833 mWaitingForDrawn.add(w);
1834 }
1835 }, true /* traverseTopToBottom */);
1836 }
1837
chaviw2fb06bc2018-01-19 17:09:15 -08001838 Dimmer getDimmer() {
1839 if (mParent == null) {
1840 return null;
1841 }
1842 return mParent.getDimmer();
1843 }
Wale Ogunwaled63594a2016-07-18 07:48:30 -07001844}