blob: 191715cfc36c9ffe1d3900346c0e7918adde66b6 [file] [log] [blame]
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001/*
2 * Copyright (C) 2011 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
Winson Chunge55c0192017-08-24 14:50:48 -070019import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Jorim Jaggic6976f02018-04-18 16:31:07 +020020import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Winson Chunge55c0192017-08-24 14:50:48 -070021import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +020022import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
Wale Ogunwale72919d22016-12-08 18:58:50 -080023import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
24import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -070025import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
Wale Ogunwale51362492016-09-08 17:49:17 -070026import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020027import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070028import static android.view.Display.DEFAULT_DISPLAY;
Jorim Jaggife762342016-10-13 14:33:27 +020029import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020030import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
Jorim Jaggife762342016-10-13 14:33:27 +020031import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070032import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080033import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070034import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
chaviw9c81e632018-07-31 11:17:52 -070035import static android.view.WindowManager.TRANSIT_UNSET;
Jorim Jaggic6976f02018-04-18 16:31:07 +020036import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
chaviw9c81e632018-07-31 11:17:52 -070037
Adrian Roose99bc052017-11-20 17:55:31 +010038import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
39import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070040import static com.android.server.wm.AppWindowTokenProto.ALL_DRAWN;
41import static com.android.server.wm.AppWindowTokenProto.APP_STOPPED;
42import static com.android.server.wm.AppWindowTokenProto.CLIENT_HIDDEN;
43import static com.android.server.wm.AppWindowTokenProto.DEFER_HIDING_CLIENT;
44import static com.android.server.wm.AppWindowTokenProto.FILLS_PARENT;
45import static com.android.server.wm.AppWindowTokenProto.FROZEN_BOUNDS;
46import static com.android.server.wm.AppWindowTokenProto.HIDDEN_REQUESTED;
47import static com.android.server.wm.AppWindowTokenProto.HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW;
48import static com.android.server.wm.AppWindowTokenProto.IS_REALLY_ANIMATING;
49import static com.android.server.wm.AppWindowTokenProto.IS_WAITING_FOR_TRANSITION_START;
50import static com.android.server.wm.AppWindowTokenProto.LAST_ALL_DRAWN;
51import static com.android.server.wm.AppWindowTokenProto.LAST_SURFACE_SHOWING;
52import static com.android.server.wm.AppWindowTokenProto.NAME;
53import static com.android.server.wm.AppWindowTokenProto.NUM_DRAWN_WINDOWS;
54import static com.android.server.wm.AppWindowTokenProto.NUM_INTERESTING_WINDOWS;
55import static com.android.server.wm.AppWindowTokenProto.REMOVED;
56import static com.android.server.wm.AppWindowTokenProto.REPORTED_DRAWN;
57import static com.android.server.wm.AppWindowTokenProto.REPORTED_VISIBLE;
58import static com.android.server.wm.AppWindowTokenProto.STARTING_DISPLAYED;
59import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED;
60import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
61import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
62import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
chaviw9c81e632018-07-31 11:17:52 -070063import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
64import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
65import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
67import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
68import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
69import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
70import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
71import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
72import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
73import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
74import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
75import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
76import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
77import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
78import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
79import static com.android.server.wm.WindowManagerService.logWithStack;
Vishnu Naira2977262018-07-26 13:31:26 -070080import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080081
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070082import android.annotation.CallSuper;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020083import android.app.Activity;
Winson Chung48b25652018-10-22 14:04:30 -070084import android.content.ComponentName;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070085import android.content.res.Configuration;
Jorim Jaggi988f6682017-11-17 17:46:43 +010086import android.graphics.GraphicBuffer;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020087import android.graphics.Point;
Jorim Jaggi0429f352015-12-22 16:29:16 +010088import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070089import android.os.Binder;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -080090import android.os.Debug;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070091import android.os.IBinder;
Steven Timotiusaf03df62017-07-18 16:56:43 -070092import android.os.RemoteException;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020093import android.os.Trace;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080094import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -070095import android.util.proto.ProtoOutputStream;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020096import android.view.DisplayInfo;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080097import android.view.IApplicationToken;
Robert Carr788f5742018-07-30 17:46:45 -070098import android.view.InputApplicationHandle;
Jorim Jaggif84e2f62018-01-16 14:17:59 +010099import android.view.RemoteAnimationDefinition;
Robert Carr6914f082017-03-20 19:04:30 -0700100import android.view.SurfaceControl;
Tony Mak64b8d562017-12-28 17:44:02 +0000101import android.view.SurfaceControl.Transaction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800102import android.view.WindowManager;
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200103import android.view.WindowManager.LayoutParams;
Tony Mak64b8d562017-12-28 17:44:02 +0000104import android.view.animation.Animation;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800105
Tony Mak64b8d562017-12-28 17:44:02 +0000106import com.android.internal.R;
Riddle Hsua118b3a2018-10-11 22:05:06 +0800107import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800108import com.android.internal.util.ToBooleanFunction;
Adrian Roose99bc052017-11-20 17:55:31 +0100109import com.android.server.policy.WindowManagerPolicy.StartingSurface;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800110import com.android.server.wm.WindowManagerService.H;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800111
112import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +0100113import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800114import java.util.ArrayList;
lumark588a3e82018-07-20 18:53:54 +0800115import java.util.function.Consumer;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800116
117class AppTokenList extends ArrayList<AppWindowToken> {
118}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800119
120/**
121 * Version of WindowToken that is specifically for a particular application (or
122 * really activity) that is displaying windows.
123 */
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700124class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800125 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
126
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100127 /**
128 * Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
129 */
130 private static final int Z_BOOST_BASE = 800570000;
131
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800132 // Non-null only for application tokens.
133 final IApplicationToken appToken;
Winson Chung48b25652018-10-22 14:04:30 -0700134 final ComponentName mActivityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800135 final boolean mVoiceInteraction;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700136
Wale Ogunwale51362492016-09-08 17:49:17 -0700137 /** @see WindowContainer#fillsParent() */
138 private boolean mFillsParent;
Craig Mautner4c5eb222013-11-18 12:59:05 -0800139 boolean layoutConfigChanges;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800140 boolean mShowForAllUsers;
141 int mTargetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -0700142
Bryce Lee6d410262017-02-28 15:30:17 -0800143 // Flag set while reparenting to prevent actions normally triggered by an individual parent
144 // change.
145 private boolean mReparenting;
146
Wale Ogunwalee287e192017-04-21 09:30:12 -0700147 // True if we are current in the process of removing this app token from the display
148 private boolean mRemovingFromDisplay = false;
149
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800150 // The input dispatching timeout for this application token in nanoseconds.
Wale Ogunwale72919d22016-12-08 18:58:50 -0800151 long mInputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800152
153 // These are used for determining when all windows associated with
154 // an activity have been drawn, so they can be made visible together
155 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -0700156 // initialize so that it doesn't match mTransactionSequence which is an int.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700157 private long mLastTransactionSequence = Long.MIN_VALUE;
158 private int mNumInterestingWindows;
159 private int mNumDrawnWindows;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800160 boolean inPendingTransaction;
161 boolean allDrawn;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000162 private boolean mLastAllDrawn;
163
Craig Mautner7636dfb2012-11-16 15:24:11 -0800164 // Set to true when this app creates a surface while in the middle of an animation. In that
165 // case do not clear allDrawn until the animation completes.
166 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800167
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800168 // Is this window's surface needed? This is almost like hidden, except
169 // it will sometimes be true a little earlier: when the token has
170 // been shown, but is still waiting for its app transition to execute
171 // before making its windows shown.
172 boolean hiddenRequested;
173
174 // Have we told the window clients to hide themselves?
Wale Ogunwale89973222017-04-23 18:39:45 -0700175 private boolean mClientHidden;
176
177 // If true we will defer setting mClientHidden to true and reporting to the client that it is
178 // hidden.
179 boolean mDeferHidingClient;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800180
181 // Last visibility state we reported to the app token.
182 boolean reportedVisible;
183
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700184 // Last drawn state we reported to the app token.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700185 private boolean reportedDrawn;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700186
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800187 // Set to true when the token has been removed from the window mgr.
188 boolean removed;
189
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800190 // Information about an application starting window if displayed.
191 StartingData startingData;
192 WindowState startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800193 StartingSurface startingSurface;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800194 boolean startingDisplayed;
195 boolean startingMoved;
Jorim Jaggi60f9c972018-02-01 19:21:07 +0100196
Wale Ogunwale6c459212017-05-17 08:56:03 -0700197 // True if the hidden state of this token was forced to false due to a transferred starting
198 // window.
199 private boolean mHiddenSetFromTransferredStartingWindow;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800200 boolean firstWindowDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700201 private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
202 new WindowState.UpdateReportedVisibilityResults();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800203
204 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700205 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800206
Wale Ogunwale571771c2016-08-26 13:18:50 -0700207 // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
Craig Mautner799bc1d2015-01-14 10:33:48 -0800208 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800209
Craig Mautnerbb742462014-07-07 15:28:55 -0700210 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700211 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700212
Wale Ogunwale72919d22016-12-08 18:58:50 -0800213 private boolean mAlwaysFocusable;
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800214
Robert Carre12aece2016-02-02 22:43:27 -0800215 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700216 int mRotationAnimationHint;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700217 private int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800218
Jorim Jaggife762342016-10-13 14:33:27 +0200219 private boolean mLastContainsShowWhenLockedWindow;
220 private boolean mLastContainsDismissKeyguardWindow;
221
Jorim Jaggi0429f352015-12-22 16:29:16 +0100222 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700223 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100224
Wale Ogunwale6c459212017-05-17 08:56:03 -0700225 private boolean mDisablePreviewScreenshots;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +0100226
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700227 private Task mLastParent;
Robert Carred3e83b2017-04-21 13:26:55 -0700228
chaviwd3bf08d2017-08-01 17:24:59 -0700229 /**
230 * See {@link #canTurnScreenOn()}
231 */
232 private boolean mCanTurnScreenOn = true;
233
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200234 /**
235 * If we are running an animation, this determines the transition type. Must be one of
236 * AppTransition.TRANSIT_* constants.
237 */
238 private int mTransit;
239
240 /**
241 * If we are running an animation, this determines the flags during this animation. Must be a
242 * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
243 */
244 private int mTransitFlags;
245
246 /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
Jorim Jaggifd1891462017-12-29 15:41:36 +0100247 private boolean mLastSurfaceShowing = true;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200248
Jorim Jaggi988f6682017-11-17 17:46:43 +0100249 private AppWindowThumbnail mThumbnail;
250
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000251 /** Have we been asked to have this token keep the screen frozen? */
252 private boolean mFreezingScreen;
253
254 /** Whether this token should be boosted at the top of all app window tokens. */
255 private boolean mNeedsZBoost;
Adrian Roos4d18a2e2017-12-19 19:08:05 +0100256 private Letterbox mLetterbox;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000257
chaviw23ee71c2017-12-18 11:29:41 -0800258 private final Point mTmpPoint = new Point();
chaviw23012112017-12-20 15:29:04 -0800259 private final Rect mTmpRect = new Rect();
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100260 private RemoteAnimationDefinition mRemoteAnimationDefinition;
Jorim Jaggi6de61012018-03-19 14:53:23 +0100261 private AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry;
chaviw23ee71c2017-12-18 11:29:41 -0800262
chaviw4ad54912018-05-30 11:05:44 -0700263 /**
264 * A flag to determine if this AWT is in the process of closing or entering PIP. This is needed
265 * to help AWT know that the app is in the process of closing but hasn't yet started closing on
266 * the WM side.
267 */
268 private boolean mWillCloseOrEnterPip;
269
Vishnu Naira2977262018-07-26 13:31:26 -0700270 /** Layer used to constrain the animation to a token's stack bounds. */
271 SurfaceControl mAnimationBoundsLayer;
272
273 /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
274 boolean mNeedsAnimationBoundsLayer;
275
Winson Chung48b25652018-10-22 14:04:30 -0700276 AppWindowToken(WindowManagerService service, IApplicationToken token,
277 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
278 long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
279 int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
280 boolean launchTaskBehind, boolean alwaysFocusable,
Bryce Leef3c6a472017-11-14 14:53:06 -0800281 AppWindowContainerController controller) {
Winson Chung48b25652018-10-22 14:04:30 -0700282 this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800283 setController(controller);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800284 mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800285 mShowForAllUsers = showForAllUsers;
286 mTargetSdk = targetSdk;
287 mOrientation = orientation;
288 layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0;
289 mLaunchTaskBehind = launchTaskBehind;
290 mAlwaysFocusable = alwaysFocusable;
291 mRotationAnimationHint = rotationAnimationHint;
292
293 // Application tokens start out hidden.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200294 setHidden(true);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800295 hiddenRequested = true;
296 }
297
Winson Chung48b25652018-10-22 14:04:30 -0700298 AppWindowToken(WindowManagerService service, IApplicationToken token,
299 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
300 boolean fillsParent) {
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800301 super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
302 false /* ownerCanManageAppTokens */);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700303 appToken = token;
Winson Chung48b25652018-10-22 14:04:30 -0700304 mActivityComponent = activityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800305 mVoiceInteraction = voiceInteraction;
Wale Ogunwale17f175c2017-02-07 16:54:10 -0800306 mFillsParent = fillsParent;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800307 mInputApplicationHandle = new InputApplicationHandle(this);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800308 }
309
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800310 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
311 firstWindowDrawn = true;
312
313 // We now have a good window to show, remove dead placeholders
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700314 removeDeadWindows();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800315
Jorim Jaggi02886a82016-12-06 09:10:06 -0800316 if (startingWindow != null) {
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800317 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
318 + win.mToken + ": first real window is shown, no animation");
319 // If this initial window is animating, stop it -- we will do an animation to reveal
320 // it from behind the starting window, so there is no need for it to also be doing its
321 // own stuff.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100322 win.cancelAnimation();
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800323 if (getController() != null) {
324 getController().removeStartingWindow();
325 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800326 }
327 updateReportedVisibilityLocked();
328 }
329
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800330 void updateReportedVisibilityLocked() {
331 if (appToken == null) {
332 return;
333 }
334
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700335 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700336 final int count = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800337
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700338 mReportedVisibilityResults.reset();
339
340 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700341 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700342 win.updateReportedVisibility(mReportedVisibilityResults);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800343 }
344
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700345 int numInteresting = mReportedVisibilityResults.numInteresting;
346 int numVisible = mReportedVisibilityResults.numVisible;
347 int numDrawn = mReportedVisibilityResults.numDrawn;
348 boolean nowGone = mReportedVisibilityResults.nowGone;
349
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700350 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200351 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !isHidden();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700352 if (!nowGone) {
353 // If the app is not yet gone, then it can only become visible/drawn.
354 if (!nowDrawn) {
355 nowDrawn = reportedDrawn;
356 }
357 if (!nowVisible) {
358 nowVisible = reportedVisible;
359 }
360 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800361 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800362 + numInteresting + " visible=" + numVisible);
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800363 final AppWindowContainerController controller = getController();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700364 if (nowDrawn != reportedDrawn) {
365 if (nowDrawn) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800366 if (controller != null) {
367 controller.reportWindowsDrawn();
368 }
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700369 }
370 reportedDrawn = nowDrawn;
371 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800372 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700373 if (DEBUG_VISIBILITY) Slog.v(TAG,
374 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800375 reportedVisible = nowVisible;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800376 if (controller != null) {
377 if (nowVisible) {
378 controller.reportWindowsVisible();
379 } else {
380 controller.reportWindowsGone();
381 }
382 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800383 }
384 }
385
Wale Ogunwale89973222017-04-23 18:39:45 -0700386 boolean isClientHidden() {
387 return mClientHidden;
388 }
389
390 void setClientHidden(boolean hideClient) {
391 if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
392 return;
393 }
Jorim Jaggi067b5bf2018-02-23 17:42:39 +0100394 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
395 + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
Wale Ogunwale89973222017-04-23 18:39:45 -0700396 mClientHidden = hideClient;
397 sendAppVisibilityToClients();
398 }
399
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700400 boolean setVisibility(WindowManager.LayoutParams lp,
401 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
402
403 boolean delayed = false;
404 inPendingTransaction = false;
Wale Ogunwale9e4721f2017-05-23 19:37:30 -0700405 // Reset the state of mHiddenSetFromTransferredStartingWindow since visibility is actually
406 // been set by the app now.
407 mHiddenSetFromTransferredStartingWindow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700408
409 // Allow for state changes and animation to be applied if:
410 // * token is transitioning visibility state
411 // * or the token was marked as hidden and is exiting before we had a chance to play the
412 // transition animation
413 // * or this is an opening app and windows are being replaced.
414 boolean visibilityChanged = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200415 if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700416 final AccessibilityController accessibilityController = mService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700417 boolean changed = false;
418 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200419 "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700420
421 boolean runningAppAnimation = false;
422
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100423 if (transit != WindowManager.TRANSIT_UNSET) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200424 if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700425 delayed = runningAppAnimation = true;
426 }
427 final WindowState window = findMainWindow();
428 //TODO (multidisplay): Magnification is supported only for the default display.
429 if (window != null && accessibilityController != null
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700430 && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700431 accessibilityController.onAppWindowTransitionLocked(window, transit);
432 }
433 changed = true;
434 }
435
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700436 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700437 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700438 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700439 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700440 }
441
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200442 setHidden(!visible);
443 hiddenRequested = !visible;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700444 visibilityChanged = true;
445 if (!visible) {
446 stopFreezingScreen(true, true);
447 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700448 // If we are being set visible, and the starting window is not yet displayed,
449 // then make sure it doesn't get displayed.
450 if (startingWindow != null && !startingWindow.isDrawnLw()) {
451 startingWindow.mPolicyVisibility = false;
452 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700453 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -0700454
455 // We are becoming visible, so better freeze the screen with the windows that are
456 // getting visible so we also wait for them.
457 forAllWindows(mService::makeWindowFreezingScreenIfNeededLocked, true);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700458 }
459
460 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setVisibility: " + this
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200461 + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700462
463 if (changed) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800464 getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700465 if (performLayout) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700466 mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700467 false /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700468 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700469 }
Arthur Hung95b38a92018-07-20 18:56:12 +0800470 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700471 }
472 }
473
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200474 if (isReallyAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700475 delayed = true;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100476 } else {
477
478 // We aren't animating anything, but exiting windows rely on the animation finished
479 // callback being called in case the AppWindowToken was pretending to be animating,
480 // which we might have done because we were in closing/opening apps list.
481 onAnimationFinished();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700482 }
483
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700484 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100485 if ((mChildren.get(i)).isSelfOrChildAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700486 delayed = true;
487 }
488 }
489
490 if (visibilityChanged) {
491 if (visible && !delayed) {
492 // The token was made immediately visible, there will be no entrance animation.
493 // We need to inform the client the enter animation was finished.
494 mEnteringAnimation = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700495 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700496 }
Robert Carr61b81112017-07-17 18:08:15 -0700497
Jorim Jaggi110839b2018-01-22 12:49:04 +0100498 // If we're becoming visible, immediately change client visibility as well although it
499 // usually gets changed in AppWindowContainerController.setVisibility already. However,
500 // there seem to be some edge cases where we change our visibility but client visibility
501 // never gets updated.
502 // If we're becoming invisible, update the client visibility if we are not running an
503 // animation. Otherwise, we'll update client visibility in onAnimationFinished.
Jorim Jaggi3cad57f2018-02-20 18:32:01 +0100504 if (visible || !isReallyAnimating()) {
Jorim Jaggi110839b2018-01-22 12:49:04 +0100505 setClientHidden(!visible);
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100506 }
507
lumark588a3e82018-07-20 18:53:54 +0800508 if (!getDisplayContent().mClosingApps.contains(this)
509 && !getDisplayContent().mOpeningApps.contains(this)) {
chaviwa953fcf2018-03-01 12:00:39 -0800510 // The token is not closing nor opening, so even if there is an animation set, that
511 // doesn't mean that it goes through the normal app transition cycle so we have
512 // to inform the docked controller about visibility change.
513 // TODO(multi-display): notify docked divider on all displays where visibility was
514 // affected.
lumark588a3e82018-07-20 18:53:54 +0800515 getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged();
chaviwa953fcf2018-03-01 12:00:39 -0800516
517 // Take the screenshot before possibly hiding the WSA, otherwise the screenshot
518 // will not be taken.
519 mService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
520 }
521
Robert Carre7cc44d2017-03-20 19:04:30 -0700522 // If we are hidden but there is no delay needed we immediately
523 // apply the Surface transaction so that the ActivityManager
Robert Carr61b81112017-07-17 18:08:15 -0700524 // can have some guarantee on the Surface state following
525 // setting the visibility. This captures cases like dismissing
526 // the docked or pinned stack where there is no app transition.
527 //
528 // In the case of a "Null" animation, there will be
529 // no animation but there will still be a transition set.
530 // We still need to delay hiding the surface such that it
531 // can be synchronized with showing the next surface in the transition.
lumark588a3e82018-07-20 18:53:54 +0800532 if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) {
Robert Carr6914f082017-03-20 19:04:30 -0700533 SurfaceControl.openTransaction();
534 for (int i = mChildren.size() - 1; i >= 0; i--) {
535 mChildren.get(i).mWinAnimator.hide("immediately hidden");
536 }
537 SurfaceControl.closeTransaction();
538 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700539 }
540
541 return delayed;
542 }
543
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200544 /**
545 * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns
546 * true.
547 */
548 WindowState getTopFullscreenWindow() {
549 for (int i = mChildren.size() - 1; i >= 0; i--) {
550 final WindowState win = mChildren.get(i);
551 if (win != null && win.mAttrs.isFullscreen()) {
552 return win;
553 }
554 }
555 return null;
556 }
557
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800558 WindowState findMainWindow() {
Matthew Ng53e66b22018-01-12 17:13:13 -0800559 return findMainWindow(true);
560 }
561
562 /**
563 * Finds the main window that either has type base application or application starting if
564 * requested.
565 *
566 * @param includeStartingApp Allow to search application-starting windows to also be returned.
567 * @return The main window of type base application or application starting if requested.
568 */
569 WindowState findMainWindow(boolean includeStartingApp) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700570 WindowState candidate = null;
Matthew Ng53e66b22018-01-12 17:13:13 -0800571 for (int j = mChildren.size() - 1; j >= 0; --j) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700572 final WindowState win = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700573 final int type = win.mAttrs.type;
574 // No need to loop through child window as base application and starting types can't be
575 // child windows.
Matthew Ng53e66b22018-01-12 17:13:13 -0800576 if (type == TYPE_BASE_APPLICATION
577 || (includeStartingApp && type == TYPE_APPLICATION_STARTING)) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700578 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900579 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700580 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800581 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700582 candidate = win;
583 } else {
584 return win;
585 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800586 }
587 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700588 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800589 }
590
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800591 boolean windowsAreFocusable() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700592 return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800593 }
594
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800595 AppWindowContainerController getController() {
596 final WindowContainerController controller = super.getController();
597 return controller != null ? (AppWindowContainerController) controller : null;
598 }
599
Wale Ogunwale571771c2016-08-26 13:18:50 -0700600 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700601 boolean isVisible() {
Wale Ogunwalee471be62016-10-03 07:53:55 -0700602 // If the app token isn't hidden then it is considered visible and there is no need to check
603 // its children windows to see if they are visible.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200604 return !isHidden();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700605 }
606
607 @Override
Wale Ogunwalee287e192017-04-21 09:30:12 -0700608 void removeImmediately() {
609 onRemovedFromDisplay();
610 super.removeImmediately();
611 }
612
613 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700614 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800615 mIsExiting = false;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800616 removeAllWindowsIfPossible();
Bryce Lee6d410262017-02-28 15:30:17 -0800617 removeImmediately();
Craig Mautnere3119b72015-01-20 15:02:36 -0800618 }
619
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700620 @Override
621 boolean checkCompleteDeferredRemoval() {
622 if (mIsExiting) {
623 removeIfPossible();
624 }
625 return super.checkCompleteDeferredRemoval();
626 }
627
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700628 void onRemovedFromDisplay() {
Wale Ogunwalee287e192017-04-21 09:30:12 -0700629 if (mRemovingFromDisplay) {
630 return;
631 }
632 mRemovingFromDisplay = true;
633
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700634 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
635
Wale Ogunwale72919d22016-12-08 18:58:50 -0800636 boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700637
lumark588a3e82018-07-20 18:53:54 +0800638 getDisplayContent().mOpeningApps.remove(this);
639 getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
Jorim Jaggi10abe2f2017-01-03 16:44:46 +0100640 mService.mTaskSnapshotController.onAppRemoved(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700641 waitingToShow = false;
lumark588a3e82018-07-20 18:53:54 +0800642 if (getDisplayContent().mClosingApps.contains(this)) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700643 delayed = true;
lumark588a3e82018-07-20 18:53:54 +0800644 } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
645 getDisplayContent().mClosingApps.add(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700646 delayed = true;
647 }
648
649 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200650 + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700651
652 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
653 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
654
Jorim Jaggi19be6052017-08-03 18:33:43 +0200655 if (startingData != null && getController() != null) {
656 getController().removeStartingWindow();
657 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800658
Winson Chung87e5d552017-04-05 11:49:38 -0700659 // If this window was animating, then we need to ensure that the app transition notifies
lumark588a3e82018-07-20 18:53:54 +0800660 // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
661 // so add to that list now
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200662 if (isSelfAnimating()) {
lumark588a3e82018-07-20 18:53:54 +0800663 getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
Winson Chung87e5d552017-04-05 11:49:38 -0700664 }
665
Wale Ogunwalee287e192017-04-21 09:30:12 -0700666 final TaskStack stack = getStack();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700667 if (delayed && !isEmpty()) {
668 // set the token aside because it has an active animation to be finished
669 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
670 "removeAppToken make exiting: " + this);
Wale Ogunwalee287e192017-04-21 09:30:12 -0700671 if (stack != null) {
672 stack.mExitingAppTokens.add(this);
673 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700674 mIsExiting = true;
675 } else {
676 // Make sure there is no animation running on this token, so any windows associated
677 // with it will be removed as soon as their animations are complete
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200678 cancelAnimation();
Wale Ogunwale3106ae012017-05-16 08:56:37 -0700679 if (stack != null) {
680 stack.mExitingAppTokens.remove(this);
681 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700682 removeIfPossible();
683 }
684
685 removed = true;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700686 stopFreezingScreen(true, true);
Bryce Lee6d410262017-02-28 15:30:17 -0800687
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800688 final DisplayContent dc = getDisplayContent();
689 if (dc.mFocusedApp == this) {
690 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
691 + " displayId=" + dc.getDisplayId());
692 dc.setFocusedApp(null);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700693 mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700694 }
695
696 if (!delayed) {
697 updateReportedVisibilityLocked();
698 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700699
700 mRemovingFromDisplay = false;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700701 }
702
Chong Zhange05bcb12016-07-26 17:47:29 -0700703 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700704 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700705 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700706 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700707 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700708 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700709 if (wallpaperMightChange) {
710 requestUpdateWallpaperIfNeeded();
711 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700712 }
713
Robert Carre12aece2016-02-02 22:43:27 -0800714 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700715 destroySurfaces(false /*cleanupOnResume*/);
716 }
717
718 /**
719 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
720 * the client has finished with them.
721 *
722 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
723 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
724 * others so that they are ready to be reused. If set to false (common case), destroy all
725 * surfaces that's eligible, if the app is already stopped.
726 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700727 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700728 boolean destroyedSomething = false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100729
730 // Copying to a different list as multiple children can be removed.
Jorim Jaggi59f3e922018-01-05 15:40:32 +0100731 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100732 for (int i = children.size() - 1; i >= 0; i--) {
733 final WindowState win = children.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700734 destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
Robert Carre12aece2016-02-02 22:43:27 -0800735 }
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700736 if (destroyedSomething) {
737 final DisplayContent dc = getDisplayContent();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700738 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Adrian Roos23df3a32018-03-15 15:41:13 +0100739 updateLetterboxSurface(null);
Robert Carre12aece2016-02-02 22:43:27 -0800740 }
741 }
742
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800743 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700744 * Notify that the app is now resumed, and it was not stopped before, perform a clean
745 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800746 */
Jorim Jaggibae01b12017-04-11 16:29:10 -0700747 void notifyAppResumed(boolean wasStopped) {
Chong Zhangad24f962016-08-25 12:12:33 -0700748 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
Jorim Jaggibae01b12017-04-11 16:29:10 -0700749 + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700750 mAppStopped = false;
chaviwd3bf08d2017-08-01 17:24:59 -0700751 // Allow the window to turn the screen on once the app is resumed again.
752 setCanTurnScreenOn(true);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700753 if (!wasStopped) {
754 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800755 }
Robert Carre12aece2016-02-02 22:43:27 -0800756 }
757
Chong Zhangbef461f2015-10-27 11:38:24 -0700758 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700759 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
760 * keeping alive in case they were still being used.
761 */
762 void notifyAppStopped() {
763 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
764 mAppStopped = true;
765 destroySurfaces();
766 // Remove any starting window that was added for this app if they are still around.
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800767 if (getController() != null) {
768 getController().removeStartingWindow();
769 }
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700770 }
771
Chong Zhang92147042016-05-09 12:47:11 -0700772 void clearAllDrawn() {
773 allDrawn = false;
774 deferClearAllDrawn = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700775 }
776
Bryce Lee6d410262017-02-28 15:30:17 -0800777 Task getTask() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800778 return (Task) getParent();
Bryce Lee6d410262017-02-28 15:30:17 -0800779 }
780
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800781 TaskStack getStack() {
782 final Task task = getTask();
783 if (task != null) {
784 return task.mStack;
785 } else {
786 return null;
787 }
788 }
789
Bryce Lee6d410262017-02-28 15:30:17 -0800790 @Override
791 void onParentSet() {
792 super.onParentSet();
793
Robert Carred3e83b2017-04-21 13:26:55 -0700794 final Task task = getTask();
795
Bryce Lee6d410262017-02-28 15:30:17 -0800796 // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
797 // access visual elements like the {@link DisplayContent}. We must remove any associations
798 // such as animations.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800799 if (!mReparenting) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800800 if (task == null) {
801 // It is possible we have been marked as a closing app earlier. We must remove ourselves
802 // from this list so we do not participate in any future animations.
lumark588a3e82018-07-20 18:53:54 +0800803 getDisplayContent().mClosingApps.remove(this);
Robert Carred3e83b2017-04-21 13:26:55 -0700804 } else if (mLastParent != null && mLastParent.mStack != null) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800805 task.mStack.mExitingAppTokens.remove(this);
806 }
Bryce Lee6d410262017-02-28 15:30:17 -0800807 }
Jorim Jaggi6de61012018-03-19 14:53:23 +0100808 final TaskStack stack = getStack();
809
810 // If we reparent, make sure to remove ourselves from the old animation registry.
811 if (mAnimatingAppWindowTokenRegistry != null) {
812 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
813 }
814 mAnimatingAppWindowTokenRegistry = stack != null
815 ? stack.getAnimatingAppWindowTokenRegistry()
816 : null;
817
Robert Carred3e83b2017-04-21 13:26:55 -0700818 mLastParent = task;
Bryce Lee6d410262017-02-28 15:30:17 -0800819 }
820
Wale Ogunwalefa854eb2016-09-20 13:43:52 -0700821 void postWindowRemoveStartingWindowCleanup(WindowState win) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700822 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700823 if (startingWindow == win) {
824 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800825 if (getController() != null) {
826 getController().removeStartingWindow();
827 }
Wale Ogunwale6c459212017-05-17 08:56:03 -0700828 } else if (mChildren.size() == 0) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700829 // If this is the last window and we had requested a starting transition window,
830 // well there is no point now.
Jorim Jaggi02886a82016-12-06 09:10:06 -0800831 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700832 startingData = null;
Wale Ogunwale6c459212017-05-17 08:56:03 -0700833 if (mHiddenSetFromTransferredStartingWindow) {
834 // We set the hidden state to false for the token from a transferred starting window.
835 // We now reset it back to true since the starting window was the last window in the
836 // token.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200837 setHidden(true);
Wale Ogunwale6c459212017-05-17 08:56:03 -0700838 }
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100839 } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700840 // If this is the last window except for a starting transition window,
841 // we need to get rid of the starting transition.
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200842 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
843 + win);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800844 if (getController() != null) {
845 getController().removeStartingWindow();
846 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700847 }
848 }
849
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700850 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700851 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700852 WindowState win = mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800853 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700854 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700855 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800856 // Set mDestroying, we don't want any animation or delayed removal here.
857 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700858 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700859 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800860 }
861 }
862 }
863
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700864 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700865 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700866 // No need to loop through child windows as the answer should be the same as that of the
867 // parent window.
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700868 if (!(mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700869 return true;
870 }
871 }
872 return false;
873 }
874
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700875 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700876 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
877 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800878
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700879 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700880 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700881 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -0800882 }
Robert Carra1eb4392015-12-10 12:43:51 -0800883 }
884
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700885 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700886 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800887 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700888 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700889 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700890 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -0800891 }
892 }
893
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700894 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700895 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
896 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800897
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700898 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700899 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700900 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -0800901 }
902 }
903
Chong Zhang4d7369a2016-04-25 16:09:14 -0700904 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700905 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700906 final WindowState w = mChildren.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -0700907 w.requestUpdateWallpaperIfNeeded();
908 }
909 }
910
Chong Zhangd78ddb42016-03-02 17:01:14 -0800911 boolean isRelaunching() {
912 return mPendingRelaunchCount > 0;
913 }
914
Robert Carr68375192017-06-13 12:41:53 -0700915 boolean shouldFreezeBounds() {
916 final Task task = getTask();
917
918 // For freeform windows, we can't freeze the bounds at the moment because this would make
919 // the resizing unresponsive.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700920 if (task == null || task.inFreeformWindowingMode()) {
Robert Carr68375192017-06-13 12:41:53 -0700921 return false;
922 }
923
924 // We freeze the bounds while drag resizing to deal with the time between
925 // the divider/drag handle being released, and the handling it's new
926 // configuration. If we are relaunched outside of the drag resizing state,
927 // we need to be careful not to do this.
928 return getTask().isDragResizing();
929 }
930
Chong Zhangd78ddb42016-03-02 17:01:14 -0800931 void startRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -0700932 if (shouldFreezeBounds()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -0800933 freezeBounds();
934 }
Robert Carrd5c7dd62017-03-08 10:39:30 -0800935
936 // In the process of tearing down before relaunching, the app will
937 // try and clean up it's child surfaces. We need to prevent this from
938 // happening, so we sever the children, transfering their ownership
939 // from the client it-self to the parent surface (owned by us).
Robert Carr29daa922018-04-27 11:56:48 -0700940 detachChildren();
941
942 mPendingRelaunchCount++;
943 }
944
945 void detachChildren() {
Robert Carrfd8e93b2018-05-10 13:40:25 -0700946 SurfaceControl.openTransaction();
Robert Carrd5c7dd62017-03-08 10:39:30 -0800947 for (int i = mChildren.size() - 1; i >= 0; i--) {
948 final WindowState w = mChildren.get(i);
949 w.mWinAnimator.detachChildren();
950 }
Robert Carrfd8e93b2018-05-10 13:40:25 -0700951 SurfaceControl.closeTransaction();
Chong Zhangd78ddb42016-03-02 17:01:14 -0800952 }
953
954 void finishRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -0700955 unfreezeBounds();
956
Chong Zhangd78ddb42016-03-02 17:01:14 -0800957 if (mPendingRelaunchCount > 0) {
958 mPendingRelaunchCount--;
Bryce Lee081554b2017-05-25 07:52:12 -0700959 } else {
960 // Update keyguard flags upon finishing relaunch.
961 checkKeyguardFlagsChanged();
Chong Zhangd78ddb42016-03-02 17:01:14 -0800962 }
963 }
964
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700965 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700966 if (mPendingRelaunchCount == 0) {
967 return;
968 }
Robert Carr68375192017-06-13 12:41:53 -0700969 unfreezeBounds();
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700970 mPendingRelaunchCount = 0;
971 }
972
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700973 /**
974 * Returns true if the new child window we are adding to this token is considered greater than
975 * the existing child window in this token in terms of z-order.
976 */
977 @Override
978 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
979 WindowState existingWindow) {
980 final int type1 = newWindow.mAttrs.type;
981 final int type2 = existingWindow.mAttrs.type;
982
983 // Base application windows should be z-ordered BELOW all other windows in the app token.
984 if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
985 return false;
986 } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
987 return true;
988 }
989
990 // Starting windows should be z-ordered ABOVE all other windows in the app token.
991 if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
992 return true;
993 } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
994 return false;
995 }
996
997 // Otherwise the new window is greater than the existing window.
998 return true;
999 }
1000
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001001 @Override
Robert Carra1eb4392015-12-10 12:43:51 -08001002 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001003 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001004
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001005 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001006 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001007 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001008 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
1009 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001010
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001011 // if we got a replacement window, reset the timeout to give drawing more time
1012 if (gotReplacementWindow) {
1013 mService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -08001014 }
Jorim Jaggife762342016-10-13 14:33:27 +02001015 checkKeyguardFlagsChanged();
1016 }
1017
1018 @Override
1019 void removeChild(WindowState child) {
1020 super.removeChild(child);
1021 checkKeyguardFlagsChanged();
Adrian Roos23df3a32018-03-15 15:41:13 +01001022 updateLetterboxSurface(child);
Robert Carra1eb4392015-12-10 12:43:51 -08001023 }
1024
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001025 private boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001026 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001027 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001028 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -08001029 return true;
1030 }
1031 }
1032 return false;
1033 }
1034
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001035 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001036 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001037 (mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -08001038 }
1039 }
1040
Winson Chung30480042017-01-26 10:55:34 -08001041 void reparent(Task task, int position) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001042 final Task currentTask = getTask();
1043 if (task == currentTask) {
Winson Chung30480042017-01-26 10:55:34 -08001044 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001045 "window token=" + this + " already child of task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001046 }
Bryce Lee6d410262017-02-28 15:30:17 -08001047
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001048 if (currentTask.mStack != task.mStack) {
Bryce Lee6d410262017-02-28 15:30:17 -08001049 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001050 "window token=" + this + " current task=" + currentTask
Bryce Lee6d410262017-02-28 15:30:17 -08001051 + " belongs to a different stack than " + task);
1052 }
1053
Winson Chung30480042017-01-26 10:55:34 -08001054 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001055 + " from task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001056 final DisplayContent prevDisplayContent = getDisplayContent();
1057
Bryce Lee6d410262017-02-28 15:30:17 -08001058 mReparenting = true;
1059
Winson Chung30480042017-01-26 10:55:34 -08001060 getParent().removeChild(this);
1061 task.addChild(this, position);
1062
Bryce Lee6d410262017-02-28 15:30:17 -08001063 mReparenting = false;
1064
Winson Chung30480042017-01-26 10:55:34 -08001065 // Relayout display(s).
1066 final DisplayContent displayContent = task.getDisplayContent();
1067 displayContent.setLayoutNeeded();
1068 if (prevDisplayContent != displayContent) {
1069 onDisplayChanged(displayContent);
1070 prevDisplayContent.setLayoutNeeded();
1071 }
1072 }
1073
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001074 @Override
1075 void onDisplayChanged(DisplayContent dc) {
1076 DisplayContent prevDc = mDisplayContent;
1077 super.onDisplayChanged(dc);
1078 if (prevDc != null && prevDc.mFocusedApp == this) {
1079 prevDc.setFocusedApp(null);
1080 if (dc.getTopStack().getTopChild().getTopChild() == this) {
1081 dc.setFocusedApp(this);
1082 }
1083 }
1084 }
1085
Jorim Jaggi0429f352015-12-22 16:29:16 +01001086 /**
1087 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
1088 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
1089 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
1090 * with a queue.
1091 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001092 private void freezeBounds() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001093 final Task task = getTask();
1094 mFrozenBounds.offer(new Rect(task.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001095
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001096 if (task.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001097 // We didn't call prepareFreezingBounds on the task, so use the current value.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001098 mFrozenMergedConfig.offer(new Configuration(task.getConfiguration()));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001099 } else {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001100 mFrozenMergedConfig.offer(new Configuration(task.mPreparedFrozenMergedConfig));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001101 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001102 // Calling unset() to make it equal to Configuration.EMPTY.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001103 task.mPreparedFrozenMergedConfig.unset();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001104 }
1105
1106 /**
1107 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
1108 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001109 private void unfreezeBounds() {
Robert Carr68375192017-06-13 12:41:53 -07001110 if (mFrozenBounds.isEmpty()) {
1111 return;
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001112 }
Robert Carr68375192017-06-13 12:41:53 -07001113 mFrozenBounds.remove();
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001114 if (!mFrozenMergedConfig.isEmpty()) {
1115 mFrozenMergedConfig.remove();
1116 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001117 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001118 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001119 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +01001120 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001121 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001122 }
1123
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001124 void setAppLayoutChanges(int changes, String reason) {
1125 if (!mChildren.isEmpty()) {
1126 final DisplayContent dc = getDisplayContent();
1127 dc.pendingLayoutChanges |= changes;
1128 if (DEBUG_LAYOUT_REPEATS) {
1129 mService.mWindowPlacerLocked.debugLayoutRepeats(reason, dc.pendingLayoutChanges);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001130 }
1131 }
1132 }
1133
1134 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001135 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001136 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001137 if (win.removeReplacedWindowIfNeeded(replacement)) {
1138 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001139 }
1140 }
1141 }
1142
1143 void startFreezingScreen() {
1144 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001145 + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001146 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001147 if (!hiddenRequested) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001148 if (!mFreezingScreen) {
1149 mFreezingScreen = true;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001150 mService.registerAppFreezeListener(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001151 mService.mAppsFreezingScreen++;
1152 if (mService.mAppsFreezingScreen == 1) {
Robert Carrae606b42018-02-15 15:36:23 -08001153 mService.startFreezingDisplayLocked(0, 0, getDisplayContent());
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001154 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1155 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001156 }
1157 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001158 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001159 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001160 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001161 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001162 }
1163 }
1164 }
1165
1166 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001167 if (!mFreezingScreen) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001168 return;
1169 }
1170 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001171 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001172 boolean unfrozeWindows = false;
1173 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001174 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001175 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001176 }
1177 if (force || unfrozeWindows) {
1178 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001179 mFreezingScreen = false;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001180 mService.unregisterAppFreezeListener(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001181 mService.mAppsFreezingScreen--;
1182 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001183 }
1184 if (unfreezeSurfaceNow) {
1185 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001186 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001187 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001188 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001189 }
1190 }
1191
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001192 @Override
1193 public void onAppFreezeTimeout() {
1194 Slog.w(TAG_WM, "Force clearing freeze: " + this);
1195 stopFreezingScreen(true, true);
1196 }
1197
Jorim Jaggi60f9c972018-02-01 19:21:07 +01001198 /**
1199 * Tries to transfer the starting window from a token that's above ourselves in the task but
1200 * not visible anymore. This is a common scenario apps use: Trampoline activity T start main
1201 * activity M in the same task. Now, when reopening the task, T starts on top of M but then
1202 * immediately finishes after, so we have to transfer T to M.
1203 */
1204 void transferStartingWindowFromHiddenAboveTokenIfNeeded() {
1205 final Task task = getTask();
1206 for (int i = task.mChildren.size() - 1; i >= 0; i--) {
1207 final AppWindowToken fromToken = task.mChildren.get(i);
1208 if (fromToken == this) {
1209 return;
1210 }
1211 if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) {
1212 return;
1213 }
1214 }
1215 }
1216
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001217 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001218 final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001219 if (fromToken == null) {
1220 return false;
1221 }
1222
1223 final WindowState tStartingWindow = fromToken.startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001224 if (tStartingWindow != null && fromToken.startingSurface != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001225 // In this case, the starting icon has already been displayed, so start
1226 // letting windows get shown immediately without any more transitions.
lumark588a3e82018-07-20 18:53:54 +08001227 getDisplayContent().mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001228
1229 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1230 + " from " + fromToken + " to " + this);
1231
1232 final long origId = Binder.clearCallingIdentity();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001233 try {
1234 // Transfer the starting window over to the new token.
1235 startingData = fromToken.startingData;
1236 startingSurface = fromToken.startingSurface;
1237 startingDisplayed = fromToken.startingDisplayed;
1238 fromToken.startingDisplayed = false;
1239 startingWindow = tStartingWindow;
1240 reportedVisible = fromToken.reportedVisible;
1241 fromToken.startingData = null;
1242 fromToken.startingSurface = null;
1243 fromToken.startingWindow = null;
1244 fromToken.startingMoved = true;
1245 tStartingWindow.mToken = this;
1246 tStartingWindow.mAppToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001247
Peter Visontay3556a3b2017-11-01 17:23:17 +00001248 if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1249 "Removing starting " + tStartingWindow + " from " + fromToken);
1250 fromToken.removeChild(tStartingWindow);
1251 fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
1252 fromToken.mHiddenSetFromTransferredStartingWindow = false;
1253 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001254
Peter Visontay3556a3b2017-11-01 17:23:17 +00001255 // Propagate other interesting state between the tokens. If the old token is displayed,
1256 // we should immediately force the new one to be displayed. If it is animating, we need
1257 // to move that animation to the new one.
1258 if (fromToken.allDrawn) {
1259 allDrawn = true;
1260 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1261 }
1262 if (fromToken.firstWindowDrawn) {
1263 firstWindowDrawn = true;
1264 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001265 if (!fromToken.isHidden()) {
1266 setHidden(false);
Peter Visontay3556a3b2017-11-01 17:23:17 +00001267 hiddenRequested = false;
1268 mHiddenSetFromTransferredStartingWindow = true;
1269 }
1270 setClientHidden(fromToken.mClientHidden);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001271
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001272 transferAnimation(fromToken);
1273
1274 // When transferring an animation, we no longer need to apply an animation to the
1275 // the token we transfer the animation over. Thus, remove the animation from
1276 // pending opening apps.
lumark588a3e82018-07-20 18:53:54 +08001277 getDisplayContent().mOpeningApps.remove(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001278
Peter Visontay3556a3b2017-11-01 17:23:17 +00001279 mService.updateFocusedWindowLocked(
1280 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
1281 getDisplayContent().setLayoutNeeded();
1282 mService.mWindowPlacerLocked.performSurfacePlacement();
1283 } finally {
1284 Binder.restoreCallingIdentity(origId);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001285 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001286 return true;
1287 } else if (fromToken.startingData != null) {
1288 // The previous app was getting ready to show a
1289 // starting window, but hasn't yet done so. Steal it!
1290 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1291 "Moving pending starting from " + fromToken + " to " + this);
1292 startingData = fromToken.startingData;
1293 fromToken.startingData = null;
1294 fromToken.startingMoved = true;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001295 if (getController() != null) {
1296 getController().scheduleAddStartingWindow();
1297 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001298 return true;
1299 }
1300
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001301 // TODO: Transfer thumbnail
1302
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001303 return false;
1304 }
1305
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001306 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001307 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001308 }
1309
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001310 @Override
1311 void onAppTransitionDone() {
1312 sendingToBottom = false;
1313 }
1314
Wale Ogunwale51362492016-09-08 17:49:17 -07001315 /**
1316 * We override because this class doesn't want its children affecting its reported orientation
1317 * in anyway.
1318 */
1319 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001320 int getOrientation(int candidate) {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001321 if (candidate == SCREEN_ORIENTATION_BEHIND) {
1322 // Allow app to specify orientation regardless of its visibility state if the current
1323 // candidate want us to use orientation behind. I.e. the visible app on-top of this one
1324 // wants us to use the orientation of the app behind it.
1325 return mOrientation;
1326 }
1327
Bryce Lee61fbcbc2017-03-10 14:14:03 -08001328 // The {@link AppWindowToken} should only specify an orientation when it is not closing or
1329 // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
1330 // an Activity in another task being started in the wrong orientation during the transition.
lumark588a3e82018-07-20 18:53:54 +08001331 if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
1332 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
Bryce Leea163b762017-01-24 11:05:01 -08001333 return mOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07001334 }
Bryce Leea163b762017-01-24 11:05:01 -08001335
1336 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001337 }
1338
Wale Ogunwaleb198b742016-12-01 08:44:09 -08001339 /** Returns the app's preferred orientation regardless of its currently visibility state. */
1340 int getOrientationIgnoreVisibility() {
1341 return mOrientation;
1342 }
1343
Craig Mautnerdbb79912012-03-01 18:59:14 -08001344 @Override
Winson Chunge55c0192017-08-24 14:50:48 -07001345 public void onConfigurationChanged(Configuration newParentConfig) {
1346 final int prevWinMode = getWindowingMode();
1347 super.onConfigurationChanged(newParentConfig);
1348 final int winMode = getWindowingMode();
1349
1350 if (prevWinMode == winMode) {
1351 return;
1352 }
1353
1354 if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) {
1355 // Entering PiP from fullscreen, reset the snap fraction
1356 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
Winson Chung82267ce2018-04-06 16:38:26 -07001357 } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED
1358 && !isHidden()) {
Winson Chunge55c0192017-08-24 14:50:48 -07001359 // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
1360 // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
1361 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
1362 if (pinnedStack != null) {
Winson Chung8efa1652018-06-06 09:34:23 -07001363 final Rect stackBounds;
1364 if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
1365 // We are animating the bounds, use the pre-animation bounds to save the snap
1366 // fraction
1367 stackBounds = pinnedStack.mPreAnimationBounds;
1368 } else {
1369 // We skip the animation if the fullscreen configuration is not compatible, so
1370 // use the current bounds to calculate the saved snap fraction instead
1371 // (see PinnedActivityStack.skipResizeAnimation())
1372 stackBounds = mTmpRect;
1373 pinnedStack.getBounds(stackBounds);
1374 }
Winson Chunge55c0192017-08-24 14:50:48 -07001375 mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
Winson Chung8efa1652018-06-06 09:34:23 -07001376 stackBounds);
Winson Chunge55c0192017-08-24 14:50:48 -07001377 }
1378 }
1379 }
1380
1381 @Override
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001382 void checkAppWindowsReadyToShow() {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001383 if (allDrawn == mLastAllDrawn) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001384 return;
1385 }
1386
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001387 mLastAllDrawn = allDrawn;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001388 if (!allDrawn) {
1389 return;
1390 }
1391
1392 // The token has now changed state to having all windows shown... what to do, what to do?
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001393 if (mFreezingScreen) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001394 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001395 stopFreezingScreen(false, true);
1396 if (DEBUG_ORIENTATION) Slog.i(TAG,
1397 "Setting mOrientationChangeComplete=true because wtoken " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001398 + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001399 // This will set mOrientationChangeComplete and cause a pass through layout.
1400 setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001401 "checkAppWindowsReadyToShow: freezingScreen");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001402 } else {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001403 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001404
1405 // We can now show all of the drawn windows!
lumark588a3e82018-07-20 18:53:54 +08001406 if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001407 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001408 }
1409 }
1410 }
1411
Matthew Ng5d23afa2017-06-21 16:16:24 -07001412 /**
Bryce Leed390deb2017-06-22 13:14:28 -07001413 * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
1414 * child {@link WindowState}. A child is considered if it has been passed into
1415 * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
1416 * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
1417 * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
1418 *
1419 * @return {@code true} If all children have been considered, {@code false}.
1420 */
1421 private boolean allDrawnStatesConsidered() {
Bryce Lee6311c4b2017-07-06 14:09:29 -07001422 for (int i = mChildren.size() - 1; i >= 0; --i) {
1423 final WindowState child = mChildren.get(i);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001424 if (child.mightAffectAllDrawn() && !child.getDrawnStateEvaluated()) {
Bryce Leed390deb2017-06-22 13:14:28 -07001425 return false;
1426 }
1427 }
1428 return true;
1429 }
1430
1431 /**
Matthew Ng5d23afa2017-06-21 16:16:24 -07001432 * Determines if the token has finished drawing. This should only be called from
1433 * {@link DisplayContent#applySurfaceChangesTransaction}
1434 */
Matthew Ng498c71d2017-04-18 13:55:45 -07001435 void updateAllDrawn() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001436 if (!allDrawn) {
Matthew Ng498c71d2017-04-18 13:55:45 -07001437 // Number of drawn windows can be less when a window is being relaunched, wait for
Bryce Leed390deb2017-06-22 13:14:28 -07001438 // all windows to be launched and drawn for this token be considered all drawn.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001439 final int numInteresting = mNumInterestingWindows;
Bryce Leed390deb2017-06-22 13:14:28 -07001440
1441 // We must make sure that all present children have been considered (determined by
1442 // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
1443 // drawn.
1444 if (numInteresting > 0 && allDrawnStatesConsidered()
1445 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001446 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001447 + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001448 allDrawn = true;
1449 // Force an additional layout pass where
1450 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
Matthew Ng498c71d2017-04-18 13:55:45 -07001451 if (mDisplayContent != null) {
1452 mDisplayContent.setLayoutNeeded();
1453 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001454 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Robert Carrecc06b32017-04-18 14:25:10 -07001455
Winson Chunge7ba6862017-05-24 12:13:33 -07001456 // Notify the pinned stack upon all windows drawn. If there was an animation in
1457 // progress then this signal will resume that animation.
Wale Ogunwale61911492017-10-11 08:50:50 -07001458 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
Winson Chunge7ba6862017-05-24 12:13:33 -07001459 if (pinnedStack != null) {
1460 pinnedStack.onAllWindowsDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -07001461 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001462 }
1463 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001464 }
1465
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001466 /**
1467 * Updated this app token tracking states for interesting and drawn windows based on the window.
1468 *
1469 * @return Returns true if the input window is considered interesting and drawn while all the
1470 * windows in this app token where not considered drawn as of the last pass.
1471 */
1472 boolean updateDrawnWindowStates(WindowState w) {
Bryce Leed390deb2017-06-22 13:14:28 -07001473 w.setDrawnStateEvaluated(true /*evaluated*/);
1474
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001475 if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001476 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001477 + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001478 }
1479
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001480 if (allDrawn && !mFreezingScreen) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001481 return false;
1482 }
1483
1484 if (mLastTransactionSequence != mService.mTransactionSequence) {
1485 mLastTransactionSequence = mService.mTransactionSequence;
Matthew Ng53e66b22018-01-12 17:13:13 -08001486 mNumDrawnWindows = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001487 startingDisplayed = false;
Matthew Ng53e66b22018-01-12 17:13:13 -08001488
1489 // There is the main base application window, even if it is exiting, wait for it
1490 mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001491 }
1492
1493 final WindowStateAnimator winAnimator = w.mWinAnimator;
1494
1495 boolean isInterestingAndDrawn = false;
1496
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001497 if (!allDrawn && w.mightAffectAllDrawn()) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001498 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1499 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001500 + ", isAnimationSet=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001501 if (!w.isDrawnLw()) {
1502 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
1503 + " pv=" + w.mPolicyVisibility
1504 + " mDrawState=" + winAnimator.drawStateToString()
1505 + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001506 + " a=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001507 }
1508 }
1509
1510 if (w != startingWindow) {
1511 if (w.isInteresting()) {
Matthew Ng53e66b22018-01-12 17:13:13 -08001512 // Add non-main window as interesting since the main app has already been added
1513 if (findMainWindow(false /* includeStartingApp */) != w) {
1514 mNumInterestingWindows++;
1515 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001516 if (w.isDrawnLw()) {
1517 mNumDrawnWindows++;
1518
1519 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
1520 + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001521 + " freezingScreen=" + mFreezingScreen
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001522 + " mAppFreezing=" + w.mAppFreezing);
1523
1524 isInterestingAndDrawn = true;
1525 }
1526 }
1527 } else if (w.isDrawnLw()) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001528 if (getController() != null) {
1529 getController().reportStartingWindowDrawn();
1530 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001531 startingDisplayed = true;
1532 }
1533 }
1534
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001535 return isInterestingAndDrawn;
1536 }
1537
Adrian Roos23df3a32018-03-15 15:41:13 +01001538 void layoutLetterbox(WindowState winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001539 final WindowState w = findMainWindow();
Adrian Roosf93b6d22018-03-21 13:48:26 +01001540 if (w == null || winHint != null && w != winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001541 return;
1542 }
Jorim Jaggia32da382018-03-28 18:01:22 +02001543 final boolean surfaceReady = w.isDrawnLw() // Regular case
Adrian Roosf93b6d22018-03-21 13:48:26 +01001544 || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
1545 || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
1546 final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001547 if (needsLetterbox) {
1548 if (mLetterbox == null) {
1549 mLetterbox = new Letterbox(() -> makeChildSurface(null));
1550 }
chaviw492139a2018-07-16 16:07:35 -07001551 mLetterbox.layout(getParent().getBounds(), w.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001552 } else if (mLetterbox != null) {
Adrian Roos23df3a32018-03-15 15:41:13 +01001553 mLetterbox.hide();
1554 }
1555 }
1556
1557 void updateLetterboxSurface(WindowState winHint) {
1558 final WindowState w = findMainWindow();
1559 if (w != winHint && winHint != null && w != null) {
1560 return;
1561 }
1562 layoutLetterbox(winHint);
1563 if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
1564 mLetterbox.applySurfaceChanges(mPendingTransaction);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001565 }
1566 }
1567
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001568 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001569 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001570 // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
1571 // before the non-exiting app tokens. So, we skip the exiting app tokens here.
1572 // TODO: Investigate if we need to continue to do this or if we can just process them
1573 // in-order.
1574 if (mIsExiting && !waitingForReplacement()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001575 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001576 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001577 return forAllWindowsUnchecked(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001578 }
1579
lumark588a3e82018-07-20 18:53:54 +08001580 @Override
1581 void forAllAppWindows(Consumer<AppWindowToken> callback) {
1582 callback.accept(this);
1583 }
1584
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001585 boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
1586 boolean traverseTopToBottom) {
1587 return super.forAllWindows(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001588 }
1589
1590 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001591 AppWindowToken asAppWindowToken() {
1592 // I am an app window token!
1593 return this;
1594 }
1595
1596 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07001597 boolean fillsParent() {
1598 return mFillsParent;
1599 }
1600
1601 void setFillsParent(boolean fillsParent) {
1602 mFillsParent = fillsParent;
1603 }
1604
Jorim Jaggife762342016-10-13 14:33:27 +02001605 boolean containsDismissKeyguardWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07001606 // Window state is transient during relaunch. We are not guaranteed to be frozen during the
1607 // entirety of the relaunch.
1608 if (isRelaunching()) {
1609 return mLastContainsDismissKeyguardWindow;
1610 }
1611
Jorim Jaggife762342016-10-13 14:33:27 +02001612 for (int i = mChildren.size() - 1; i >= 0; i--) {
1613 if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
1614 return true;
1615 }
1616 }
1617 return false;
1618 }
1619
1620 boolean containsShowWhenLockedWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07001621 // When we are relaunching, it is possible for us to be unfrozen before our previous
1622 // windows have been added back. Using the cached value ensures that our previous
1623 // showWhenLocked preference is honored until relaunching is complete.
1624 if (isRelaunching()) {
1625 return mLastContainsShowWhenLockedWindow;
1626 }
1627
Jorim Jaggife762342016-10-13 14:33:27 +02001628 for (int i = mChildren.size() - 1; i >= 0; i--) {
1629 if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
1630 return true;
1631 }
1632 }
Bryce Lee081554b2017-05-25 07:52:12 -07001633
Jorim Jaggife762342016-10-13 14:33:27 +02001634 return false;
1635 }
1636
1637 void checkKeyguardFlagsChanged() {
1638 final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
1639 final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
1640 if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
1641 || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
lumark588a3e82018-07-20 18:53:54 +08001642 mService.notifyKeyguardFlagsChanged(null /* callback */,
1643 getDisplayContent().getDisplayId());
Jorim Jaggife762342016-10-13 14:33:27 +02001644 }
1645 mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
1646 mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
1647 }
1648
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001649 WindowState getImeTargetBelowWindow(WindowState w) {
1650 final int index = mChildren.indexOf(w);
1651 if (index > 0) {
1652 final WindowState target = mChildren.get(index - 1);
1653 if (target.canBeImeTarget()) {
1654 return target;
1655 }
1656 }
1657 return null;
1658 }
1659
1660 WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
1661 WindowState candidate = null;
1662 for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
1663 final WindowState w = mChildren.get(i);
1664 if (w.mRemoved) {
1665 continue;
1666 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02001667 if (candidate == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001668 candidate = w;
1669 }
1670 }
1671 return candidate;
1672 }
1673
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001674 /**
1675 * See {@link Activity#setDisablePreviewScreenshots}.
1676 */
1677 void setDisablePreviewScreenshots(boolean disable) {
Wale Ogunwale6c459212017-05-17 08:56:03 -07001678 mDisablePreviewScreenshots = disable;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01001679 }
1680
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001681 /**
chaviwd3bf08d2017-08-01 17:24:59 -07001682 * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
1683 */
1684 void setCanTurnScreenOn(boolean canTurnScreenOn) {
1685 mCanTurnScreenOn = canTurnScreenOn;
1686 }
1687
1688 /**
1689 * Indicates whether the current launch can turn the screen on. This is to prevent multiple
1690 * relayouts from turning the screen back on. The screen should only turn on at most
1691 * once per activity resume.
1692 *
1693 * @return true if the screen can be turned on.
1694 */
1695 boolean canTurnScreenOn() {
1696 return mCanTurnScreenOn;
1697 }
1698
1699 /**
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001700 * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
1701 * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
1702 * we can't take a snapshot for other reasons, for example, if we have a secure window.
1703 *
1704 * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
1705 * screenshot.
1706 */
1707 boolean shouldUseAppThemeSnapshot() {
Wale Ogunwale6c459212017-05-17 08:56:03 -07001708 return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001709 true /* topToBottom */);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01001710 }
1711
Jorim Jaggibe418292018-03-26 16:14:12 +02001712 SurfaceControl getAppAnimationLayer() {
Jorim Jaggi391790622018-04-18 15:30:44 +02001713 return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
1714 : needsZBoost() ? ANIMATION_LAYER_BOOSTED
1715 : ANIMATION_LAYER_STANDARD);
Jorim Jaggibe418292018-03-26 16:14:12 +02001716 }
1717
chaviw23ee71c2017-12-18 11:29:41 -08001718 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +01001719 public SurfaceControl getAnimationLeashParent() {
Robert Carrb9506032018-02-13 13:54:00 -08001720 // All normal app transitions take place in an animation layer which is below the pinned
1721 // stack but may be above the parent stacks of the given animating apps.
1722 // For transitions in the pinned stack (menu activity) we just let them occur as a child
1723 // of the pinned stack.
1724 if (!inPinnedWindowingMode()) {
1725 return getAppAnimationLayer();
1726 } else {
1727 return getStack().getSurfaceControl();
1728 }
chaviw23ee71c2017-12-18 11:29:41 -08001729 }
1730
Jorim Jaggic6976f02018-04-18 16:31:07 +02001731 private boolean shouldAnimate(int transit) {
1732 final boolean isSplitScreenPrimary =
1733 getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
1734 final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
1735
1736 // We animate always if it's not split screen primary, and only some special cases in split
1737 // screen primary because it causes issues with stack clipping when we run an un-minimize
1738 // animation at the same time.
1739 return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
1740 }
1741
Vishnu Naira2977262018-07-26 13:31:26 -07001742 /**
1743 * Creates a layer to apply crop to an animation.
1744 */
1745 private SurfaceControl createAnimationBoundsLayer(Transaction t) {
1746 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
1747 final SurfaceControl.Builder builder = makeAnimationLeash()
1748 .setParent(getAnimationLeashParent())
1749 .setName(getSurfaceControl() + " - animation-bounds")
1750 .setSize(getSurfaceWidth(), getSurfaceHeight());
1751 final SurfaceControl boundsLayer = builder.build();
Vishnu Naird454442d2018-11-13 13:51:01 -08001752 t.setWindowCrop(boundsLayer, getSurfaceWidth(), getSurfaceHeight());
Vishnu Naira2977262018-07-26 13:31:26 -07001753 t.show(boundsLayer);
1754 return boundsLayer;
1755 }
1756
Riddle Hsua118b3a2018-10-11 22:05:06 +08001757 /** Get position and crop region of animation. */
1758 @VisibleForTesting
1759 void getAnimationBounds(Point outPosition, Rect outBounds) {
1760 outPosition.set(0, 0);
1761 outBounds.setEmpty();
1762
1763 final TaskStack stack = getStack();
1764 final Task task = getTask();
1765 if (task != null && task.inFreeformWindowingMode()) {
1766 task.getRelativePosition(outPosition);
1767 } else if (stack != null) {
1768 stack.getRelativePosition(outPosition);
1769 }
1770
1771 // Always use stack bounds in order to have the ability to animate outside the task region.
1772 // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
1773 // according to the bounds.
1774 if (stack != null) {
1775 stack.getBounds(outBounds);
1776 }
1777 // We have the relative position so the local position can be removed from bounds.
1778 outBounds.offsetTo(0, 0);
1779 }
1780
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001781 boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
1782 boolean isVoiceInteraction) {
1783
Jorim Jaggic6976f02018-04-18 16:31:07 +02001784 if (mService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001785 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Jorim Jaggic6976f02018-04-18 16:31:07 +02001786 Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
1787 + " atoken=" + this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001788 }
1789 cancelAnimation();
1790 return false;
1791 }
1792
1793 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
1794 // to animate and it can cause strange artifacts when we unfreeze the display if some
1795 // different animation is running.
1796 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
1797 if (okToAnimate()) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001798 final AnimationAdapter adapter;
Riddle Hsua118b3a2018-10-11 22:05:06 +08001799 getAnimationBounds(mTmpPoint, mTmpRect);
Jorim Jaggic4d29f22018-03-22 16:30:56 +01001800
1801 // Delaying animation start isn't compatible with remote animations at all.
lumark588a3e82018-07-20 18:53:54 +08001802 if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
Jorim Jaggic4d29f22018-03-22 16:30:56 +01001803 && !mSurfaceAnimator.isAnimationStartDelayed()) {
lumark588a3e82018-07-20 18:53:54 +08001804 adapter = getDisplayContent().mAppTransition.getRemoteAnimationController()
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001805 .createAnimationAdapter(this, mTmpPoint, mTmpRect);
1806 } else {
lumark588a3e82018-07-20 18:53:54 +08001807 final int appStackClipMode =
1808 getDisplayContent().mAppTransition.getAppStackClipMode();
Vishnu Naira2977262018-07-26 13:31:26 -07001809 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
1810
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001811 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
1812 if (a != null) {
1813 adapter = new LocalAnimationAdapter(
1814 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
lumark588a3e82018-07-20 18:53:54 +08001815 getDisplayContent().mAppTransition.canSkipFirstFrame(),
Vishnu Naira2977262018-07-26 13:31:26 -07001816 appStackClipMode,
Jorim Jaggiaa763cd2018-03-22 23:20:36 +01001817 true /* isAppAnimation */),
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001818 mService.mSurfaceAnimationRunner);
1819 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
1820 mNeedsZBoost = true;
1821 }
1822 mTransit = transit;
lumark588a3e82018-07-20 18:53:54 +08001823 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001824 } else {
1825 adapter = null;
chaviw23ee71c2017-12-18 11:29:41 -08001826 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001827 }
1828 if (adapter != null) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001829 startAnimation(getPendingTransaction(), adapter, !isVisible());
Jorim Jaggi82c17862018-02-21 17:50:18 +01001830 if (adapter.getShowWallpaper()) {
1831 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1832 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001833 }
1834 } else {
1835 cancelAnimation();
1836 }
1837 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
1838
1839 return isReallyAnimating();
1840 }
1841
1842 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
1843 boolean isVoiceInteraction) {
1844 final DisplayContent displayContent = getTask().getDisplayContent();
1845 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1846 final int width = displayInfo.appWidth;
1847 final int height = displayInfo.appHeight;
1848 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
1849 "applyAnimation: atoken=" + this);
1850
1851 // Determine the visible rect to calculate the thumbnail clip
1852 final WindowState win = findMainWindow();
1853 final Rect frame = new Rect(0, 0, width, height);
1854 final Rect displayFrame = new Rect(0, 0,
1855 displayInfo.logicalWidth, displayInfo.logicalHeight);
1856 final Rect insets = new Rect();
1857 final Rect stableInsets = new Rect();
1858 Rect surfaceInsets = null;
1859 final boolean freeform = win != null && win.inFreeformWindowingMode();
1860 if (win != null) {
1861 // Containing frame will usually cover the whole screen, including dialog windows.
1862 // For freeform workspace windows it will not cover the whole screen and it also
1863 // won't exactly match the final freeform window frame (e.g. when overlapping with
1864 // the status bar). In that case we need to use the final frame.
1865 if (freeform) {
chaviw492139a2018-07-16 16:07:35 -07001866 frame.set(win.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001867 } else if (win.isLetterboxedAppWindow()) {
1868 frame.set(getTask().getBounds());
Winson Chungc1674272018-02-21 10:15:17 -08001869 } else if (win.isDockedResizing()) {
1870 // If we are animating while docked resizing, then use the stack bounds as the
1871 // animation target (which will be different than the task bounds)
1872 frame.set(getTask().getParent().getBounds());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001873 } else {
chaviw553b0212018-07-12 13:37:01 -07001874 frame.set(win.getContainingFrame());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001875 }
1876 surfaceInsets = win.getAttrs().surfaceInsets;
Adrian Roos20e07892018-02-23 19:12:01 +01001877 // XXX(b/72757033): These are insets relative to the window frame, but we're really
1878 // interested in the insets relative to the frame we chose in the if-blocks above.
chaviw9c81e632018-07-31 11:17:52 -07001879 win.getContentInsets(insets);
1880 win.getStableInsets(stableInsets);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001881 }
1882
1883 if (mLaunchTaskBehind) {
1884 // Differentiate the two animations. This one which is briefly on the screen
1885 // gets the !enter animation, and the other activity which remains on the
1886 // screen gets the enter animation. Both appear in the mOpeningApps set.
1887 enter = false;
1888 }
1889 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
1890 + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
1891 + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
1892 final Configuration displayConfig = displayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08001893 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001894 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
1895 surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
1896 if (a != null) {
1897 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
1898 final int containingWidth = frame.width();
1899 final int containingHeight = frame.height();
1900 a.initialize(containingWidth, containingHeight, width, height);
1901 a.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1902 }
1903 return a;
1904 }
1905
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001906 @Override
Jorim Jaggi6de61012018-03-19 14:53:23 +01001907 public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
1908 return mAnimatingAppWindowTokenRegistry != null
1909 && mAnimatingAppWindowTokenRegistry.notifyAboutToFinish(
1910 this, endDeferFinishCallback);
1911 }
1912
1913 @Override
1914 public void onAnimationLeashDestroyed(Transaction t) {
1915 super.onAnimationLeashDestroyed(t);
Vishnu Naira2977262018-07-26 13:31:26 -07001916 if (mAnimationBoundsLayer != null) {
1917 t.destroy(mAnimationBoundsLayer);
1918 mAnimationBoundsLayer = null;
1919 }
1920
Jorim Jaggi6de61012018-03-19 14:53:23 +01001921 if (mAnimatingAppWindowTokenRegistry != null) {
1922 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
1923 }
1924 }
1925
1926 @Override
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001927 protected void setLayer(Transaction t, int layer) {
1928 if (!mSurfaceAnimator.hasLeash()) {
1929 t.setLayer(mSurfaceControl, layer);
1930 }
1931 }
1932
1933 @Override
1934 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
1935 if (!mSurfaceAnimator.hasLeash()) {
1936 t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
1937 }
1938 }
1939
1940 @Override
1941 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
1942 if (!mSurfaceAnimator.hasLeash()) {
1943 t.reparent(mSurfaceControl, newParent.getHandle());
1944 }
1945 }
1946
1947 @Override
1948 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001949 // The leash is parented to the animation layer. We need to preserve the z-order by using
1950 // the prefix order index, but we boost if necessary.
Robert Carrb9506032018-02-13 13:54:00 -08001951 int layer = 0;
1952 if (!inPinnedWindowingMode()) {
1953 layer = getPrefixOrderIndex();
1954 } else {
1955 // Pinned stacks have animations take place within themselves rather than an animation
1956 // layer so we need to preserve the order relative to the stack (e.g. the order of our
1957 // task/parent).
1958 layer = getParent().getPrefixOrderIndex();
1959 }
1960
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001961 if (mNeedsZBoost) {
1962 layer += Z_BOOST_BASE;
1963 }
1964 leash.setLayer(layer);
Robert Carr2f8aa392018-01-31 14:46:51 -08001965
1966 final DisplayContent dc = getDisplayContent();
Jorim Jaggibe418292018-03-26 16:14:12 +02001967 dc.assignStackOrdering();
Jorim Jaggi6de61012018-03-19 14:53:23 +01001968 if (mAnimatingAppWindowTokenRegistry != null) {
1969 mAnimatingAppWindowTokenRegistry.notifyStarting(this);
1970 }
Vishnu Naira2977262018-07-26 13:31:26 -07001971
1972 // If the animation needs to be cropped then an animation bounds layer is created as a child
1973 // of the pinned stack or animation layer. The leash is then reparented to this new layer.
1974 if (mNeedsAnimationBoundsLayer) {
1975 final TaskStack stack = getStack();
1976 if (stack == null) {
1977 return;
1978 }
1979 mAnimationBoundsLayer = createAnimationBoundsLayer(t);
1980
1981 // Set clip rect to stack bounds.
1982 mTmpRect.setEmpty();
1983 stack.getBounds(mTmpRect);
1984
1985 // Crop to stack bounds.
1986 t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
1987
1988 // Reparent leash to animation bounds layer.
1989 t.reparent(leash, mAnimationBoundsLayer.getHandle());
1990 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001991 }
1992
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001993 /**
1994 * This must be called while inside a transaction.
1995 */
1996 void showAllWindowsLocked() {
1997 forAllWindows(windowState -> {
1998 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + windowState);
1999 windowState.performShowLocked();
2000 }, false /* traverseTopToBottom */);
Jorim Jaggia5e10572017-11-15 14:36:26 +01002001 }
2002
2003 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002004 protected void onAnimationFinished() {
2005 super.onAnimationFinished();
2006
2007 mTransit = TRANSIT_UNSET;
2008 mTransitFlags = 0;
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002009 mNeedsZBoost = false;
Vishnu Naira2977262018-07-26 13:31:26 -07002010 mNeedsAnimationBoundsLayer = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002011
2012 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
2013 "AppWindowToken");
2014
Jorim Jaggi988f6682017-11-17 17:46:43 +01002015 clearThumbnail();
Jorim Jaggi752cd822018-03-29 16:29:18 +02002016 setClientHidden(isHidden() && hiddenRequested);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002017
lumarkff0ab692018-11-05 20:32:30 +08002018 getDisplayContent().computeImeTargetIfNeeded(this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002019
2020 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this
2021 + ": reportedVisible=" + reportedVisible
2022 + " okToDisplay=" + okToDisplay()
2023 + " okToAnimate=" + okToAnimate()
2024 + " startingDisplayed=" + startingDisplayed);
2025
2026 // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
2027 // traverse the copy.
2028 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
2029 children.forEach(WindowState::onExitAnimationDone);
2030
lumark588a3e82018-07-20 18:53:54 +08002031 getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002032 scheduleAnimation();
2033 }
2034
2035 @Override
2036 boolean isAppAnimating() {
2037 return isSelfAnimating();
2038 }
2039
2040 @Override
2041 boolean isSelfAnimating() {
2042 // If we are about to start a transition, we also need to be considered animating.
2043 return isWaitingForTransitionStart() || isReallyAnimating();
2044 }
2045
2046 /**
2047 * @return True if and only if we are actually running an animation. Note that
2048 * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
2049 * start.
2050 */
2051 private boolean isReallyAnimating() {
2052 return super.isSelfAnimating();
2053 }
2054
Jorim Jaggi988f6682017-11-17 17:46:43 +01002055 @Override
2056 void cancelAnimation() {
2057 super.cancelAnimation();
2058 clearThumbnail();
2059 }
2060
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002061 boolean isWaitingForTransitionStart() {
lumark588a3e82018-07-20 18:53:54 +08002062 return getDisplayContent().mAppTransition.isTransitionSet()
2063 && (getDisplayContent().mOpeningApps.contains(this)
2064 || getDisplayContent().mClosingApps.contains(this));
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002065 }
2066
2067 public int getTransit() {
2068 return mTransit;
2069 }
2070
2071 int getTransitFlags() {
2072 return mTransitFlags;
2073 }
2074
Jorim Jaggi988f6682017-11-17 17:46:43 +01002075 void attachThumbnailAnimation() {
2076 if (!isReallyAnimating()) {
2077 return;
2078 }
2079 final int taskId = getTask().mTaskId;
2080 final GraphicBuffer thumbnailHeader =
lumark588a3e82018-07-20 18:53:54 +08002081 getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002082 if (thumbnailHeader == null) {
2083 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
2084 return;
2085 }
2086 clearThumbnail();
2087 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
2088 mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
2089 }
2090
Tony Mak64b8d562017-12-28 17:44:02 +00002091 /**
2092 * Attaches a surface with a thumbnail for the
2093 * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
2094 */
2095 void attachCrossProfileAppsThumbnailAnimation() {
2096 if (!isReallyAnimating()) {
2097 return;
2098 }
2099 clearThumbnail();
2100
2101 final WindowState win = findMainWindow();
2102 if (win == null) {
2103 return;
2104 }
chaviw492139a2018-07-16 16:07:35 -07002105 final Rect frame = win.getFrameLw();
Tony Mak64b8d562017-12-28 17:44:02 +00002106 final int thumbnailDrawableRes = getTask().mUserId == mService.mCurrentUserId
2107 ? R.drawable.ic_account_circle
Tony Makda4af232018-04-27 11:01:10 +01002108 : R.drawable.ic_corp_badge;
Tony Mak64b8d562017-12-28 17:44:02 +00002109 final GraphicBuffer thumbnail =
lumark588a3e82018-07-20 18:53:54 +08002110 getDisplayContent().mAppTransition
Tony Mak64b8d562017-12-28 17:44:02 +00002111 .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
2112 if (thumbnail == null) {
2113 return;
2114 }
2115 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
2116 final Animation animation =
lumark588a3e82018-07-20 18:53:54 +08002117 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
chaviw492139a2018-07-16 16:07:35 -07002118 win.getFrameLw());
Tony Mak64b8d562017-12-28 17:44:02 +00002119 mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
2120 frame.top));
2121 }
2122
Jorim Jaggi988f6682017-11-17 17:46:43 +01002123 private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
2124 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
2125
2126 // If this is a multi-window scenario, we use the windows frame as
2127 // destination of the thumbnail header animation. If this is a full screen
2128 // window scenario, we use the whole display as the target.
2129 WindowState win = findMainWindow();
2130 Rect appRect = win != null ? win.getContentFrameLw() :
2131 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
chaviw9c81e632018-07-31 11:17:52 -07002132 final Rect insets = win != null ? win.getContentInsets() : null;
Jorim Jaggi988f6682017-11-17 17:46:43 +01002133 final Configuration displayConfig = mDisplayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002134 return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
Jorim Jaggi988f6682017-11-17 17:46:43 +01002135 appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
2136 displayConfig.orientation);
2137 }
2138
2139 private void clearThumbnail() {
2140 if (mThumbnail == null) {
2141 return;
2142 }
2143 mThumbnail.destroy();
2144 mThumbnail = null;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002145 }
2146
Jorim Jaggif84e2f62018-01-16 14:17:59 +01002147 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
2148 mRemoteAnimationDefinition = definition;
2149 }
2150
2151 RemoteAnimationDefinition getRemoteAnimationDefinition() {
2152 return mRemoteAnimationDefinition;
2153 }
2154
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002155 @Override
2156 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2157 super.dump(pw, prefix, dumpAll);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002158 if (appToken != null) {
Wale Ogunwale72919d22016-12-08 18:58:50 -08002159 pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002160 }
Winson Chung48b25652018-10-22 14:04:30 -07002161 pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08002162 pw.print(prefix); pw.print("task="); pw.println(getTask());
Wale Ogunwale51362492016-09-08 17:49:17 -07002163 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
2164 pw.print(" mOrientation="); pw.println(mOrientation);
Wale Ogunwale89973222017-04-23 18:39:45 -07002165 pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
2166 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
2167 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07002168 if (paused) {
2169 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002170 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08002171 if (mAppStopped) {
2172 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
2173 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002174 if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002175 || allDrawn || mLastAllDrawn) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002176 pw.print(prefix); pw.print("mNumInterestingWindows=");
2177 pw.print(mNumInterestingWindows);
2178 pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002179 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07002180 pw.print(" allDrawn="); pw.print(allDrawn);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002181 pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
Craig Mautner6fbda632012-07-03 09:26:39 -07002182 pw.println(")");
2183 }
2184 if (inPendingTransaction) {
2185 pw.print(prefix); pw.print("inPendingTransaction=");
2186 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002187 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08002188 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002189 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
2190 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08002191 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08002192 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002193 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002194 if (startingWindow != null || startingSurface != null
Wale Ogunwale6c459212017-05-17 08:56:03 -07002195 || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002196 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002197 pw.print(" startingSurface="); pw.print(startingSurface);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002198 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale6c459212017-05-17 08:56:03 -07002199 pw.print(" startingMoved="); pw.print(startingMoved);
2200 pw.println(" mHiddenSetFromTransferredStartingWindow="
2201 + mHiddenSetFromTransferredStartingWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002202 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01002203 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08002204 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002205 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08002206 }
2207 if (mPendingRelaunchCount != 0) {
2208 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01002209 }
Wale Ogunwale9c64cb62017-04-12 13:39:59 -07002210 if (getController() != null) {
2211 pw.print(prefix); pw.print("controller="); pw.println(getController());
2212 }
Wale Ogunwalee287e192017-04-21 09:30:12 -07002213 if (mRemovingFromDisplay) {
2214 pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
2215 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002216 }
2217
2218 @Override
2219 void setHidden(boolean hidden) {
2220 super.setHidden(hidden);
Winson Chunge55c0192017-08-24 14:50:48 -07002221
2222 if (hidden) {
2223 // Once the app window is hidden, reset the last saved PiP snap fraction
2224 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
2225 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002226 scheduleAnimation();
2227 }
2228
2229 @Override
2230 void prepareSurfaces() {
2231 // isSelfAnimating also returns true when we are about to start a transition, so we need
2232 // to check super here.
2233 final boolean reallyAnimating = super.isSelfAnimating();
2234 final boolean show = !isHidden() || reallyAnimating;
2235 if (show && !mLastSurfaceShowing) {
2236 mPendingTransaction.show(mSurfaceControl);
2237 } else if (!show && mLastSurfaceShowing) {
2238 mPendingTransaction.hide(mSurfaceControl);
Jorim Jaggi4d1835d2017-08-31 17:28:27 +02002239 }
Jorim Jaggi988f6682017-11-17 17:46:43 +01002240 if (mThumbnail != null) {
2241 mThumbnail.setShowing(mPendingTransaction, show);
2242 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002243 mLastSurfaceShowing = show;
2244 super.prepareSurfaces();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002245 }
2246
Jorim Jaggi77d0f36c2018-03-16 17:49:49 +01002247 /**
2248 * @return Whether our {@link #getSurfaceControl} is currently showing.
2249 */
2250 boolean isSurfaceShowing() {
2251 return mLastSurfaceShowing;
2252 }
2253
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002254 boolean isFreezingScreen() {
2255 return mFreezingScreen;
2256 }
2257
2258 @Override
2259 boolean needsZBoost() {
2260 return mNeedsZBoost || super.needsZBoost();
2261 }
2262
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07002263 @CallSuper
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002264 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02002265 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07002266 final long token = proto.start(fieldId);
2267 writeNameToProto(proto, NAME);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002268 super.writeToProto(proto, WINDOW_TOKEN, trim);
Vishnu Nair04ab4392018-01-10 11:00:06 -08002269 proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
2270 proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
2271 proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
2272 if (mThumbnail != null){
2273 mThumbnail.writeToProto(proto, THUMBNAIL);
2274 }
2275 proto.write(FILLS_PARENT, mFillsParent);
2276 proto.write(APP_STOPPED, mAppStopped);
2277 proto.write(HIDDEN_REQUESTED, hiddenRequested);
2278 proto.write(CLIENT_HIDDEN, mClientHidden);
2279 proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
2280 proto.write(REPORTED_DRAWN, reportedDrawn);
2281 proto.write(REPORTED_VISIBLE, reportedVisible);
2282 proto.write(NUM_INTERESTING_WINDOWS, mNumInterestingWindows);
2283 proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
2284 proto.write(ALL_DRAWN, allDrawn);
2285 proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
2286 proto.write(REMOVED, removed);
2287 if (startingWindow != null){
2288 startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
2289 }
2290 proto.write(STARTING_DISPLAYED, startingDisplayed);
2291 proto.write(STARTING_MOVED, startingMoved);
2292 proto.write(HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW,
2293 mHiddenSetFromTransferredStartingWindow);
2294 for (Rect bounds : mFrozenBounds) {
2295 bounds.writeToProto(proto, FROZEN_BOUNDS);
2296 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002297 proto.end(token);
2298 }
2299
2300 void writeNameToProto(ProtoOutputStream proto, long fieldId) {
2301 if (appToken == null) {
2302 return;
2303 }
2304 try {
2305 proto.write(fieldId, appToken.getName());
2306 } catch (RemoteException e) {
2307 // This shouldn't happen, but in this case fall back to outputting nothing
2308 Slog.e(TAG, e.toString());
2309 }
2310 }
2311
2312 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002313 public String toString() {
2314 if (stringName == null) {
2315 StringBuilder sb = new StringBuilder();
2316 sb.append("AppWindowToken{");
2317 sb.append(Integer.toHexString(System.identityHashCode(this)));
2318 sb.append(" token="); sb.append(token); sb.append('}');
2319 stringName = sb.toString();
2320 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002321 return stringName + ((mIsExiting) ? " mIsExiting=" : "");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002322 }
Adrian Roos20e07892018-02-23 19:12:01 +01002323
2324 Rect getLetterboxInsets() {
2325 if (mLetterbox != null) {
2326 return mLetterbox.getInsets();
2327 } else {
2328 return new Rect();
2329 }
2330 }
Adrian Roos23df3a32018-03-15 15:41:13 +01002331
2332 /**
2333 * @eturn true if there is a letterbox and any part of that letterbox overlaps with
2334 * the given {@code rect}.
2335 */
2336 boolean isLetterboxOverlappingWith(Rect rect) {
2337 return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
2338 }
chaviw4ad54912018-05-30 11:05:44 -07002339
2340 /**
2341 * Sets if this AWT is in the process of closing or entering PIP.
2342 * {@link #mWillCloseOrEnterPip}}
2343 */
2344 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
2345 mWillCloseOrEnterPip = willCloseOrEnterPip;
2346 }
2347
2348 /**
2349 * Returns whether this AWT is considered closing. Conditions are either
2350 * 1. Is this app animating and was requested to be hidden
2351 * 2. App is delayed closing since it might enter PIP.
2352 */
2353 boolean isClosingOrEnteringPip() {
2354 return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
2355 }
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +02002356
2357 /**
2358 * @return Whether we are allowed to show non-starting windows at the moment. We disallow
2359 * showing windows during transitions in case we have windows that have wide-color-gamut
2360 * color mode set to avoid jank in the middle of the transition.
2361 */
2362 boolean canShowWindows() {
2363 return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
2364 }
2365
2366 /**
2367 * @return true if we have a window that has a non-default color mode set; false otherwise.
2368 */
2369 private boolean hasNonDefaultColorWindow() {
2370 return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
2371 true /* topToBottom */);
2372 }
lumark588a3e82018-07-20 18:53:54 +08002373
2374 void removeFromPendingTransition() {
2375 if (isWaitingForTransitionStart() && mDisplayContent != null) {
2376 mDisplayContent.mOpeningApps.remove(this);
2377 mDisplayContent.mClosingApps.remove(this);
2378 }
2379 }
Jeff Browne9bdb312012-04-05 15:30:10 -07002380}