blob: 52c78cea439cdc34f1cbf94cee9096a8e7ae2810 [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 }
Vishnu Nair9ba31652018-11-13 14:34:05 -0800369 } else {
370 if (controller != null) {
371 controller.reportWindowsNotDrawn();
372 }
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700373 }
374 reportedDrawn = nowDrawn;
375 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800376 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700377 if (DEBUG_VISIBILITY) Slog.v(TAG,
378 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800379 reportedVisible = nowVisible;
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800380 if (controller != null) {
381 if (nowVisible) {
382 controller.reportWindowsVisible();
383 } else {
384 controller.reportWindowsGone();
385 }
386 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800387 }
388 }
389
Wale Ogunwale89973222017-04-23 18:39:45 -0700390 boolean isClientHidden() {
391 return mClientHidden;
392 }
393
394 void setClientHidden(boolean hideClient) {
395 if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
396 return;
397 }
Jorim Jaggi067b5bf2018-02-23 17:42:39 +0100398 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
399 + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
Wale Ogunwale89973222017-04-23 18:39:45 -0700400 mClientHidden = hideClient;
401 sendAppVisibilityToClients();
402 }
403
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700404 boolean setVisibility(WindowManager.LayoutParams lp,
405 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
406
407 boolean delayed = false;
408 inPendingTransaction = false;
Wale Ogunwale9e4721f2017-05-23 19:37:30 -0700409 // Reset the state of mHiddenSetFromTransferredStartingWindow since visibility is actually
410 // been set by the app now.
411 mHiddenSetFromTransferredStartingWindow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700412
413 // Allow for state changes and animation to be applied if:
414 // * token is transitioning visibility state
415 // * or the token was marked as hidden and is exiting before we had a chance to play the
416 // transition animation
417 // * or this is an opening app and windows are being replaced.
418 boolean visibilityChanged = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200419 if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700420 final AccessibilityController accessibilityController = mService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700421 boolean changed = false;
422 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200423 "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700424
425 boolean runningAppAnimation = false;
426
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100427 if (transit != WindowManager.TRANSIT_UNSET) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200428 if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700429 delayed = runningAppAnimation = true;
430 }
431 final WindowState window = findMainWindow();
432 //TODO (multidisplay): Magnification is supported only for the default display.
433 if (window != null && accessibilityController != null
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700434 && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700435 accessibilityController.onAppWindowTransitionLocked(window, transit);
436 }
437 changed = true;
438 }
439
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700440 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700441 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700442 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700443 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700444 }
445
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200446 setHidden(!visible);
447 hiddenRequested = !visible;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700448 visibilityChanged = true;
449 if (!visible) {
450 stopFreezingScreen(true, true);
451 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700452 // If we are being set visible, and the starting window is not yet displayed,
453 // then make sure it doesn't get displayed.
454 if (startingWindow != null && !startingWindow.isDrawnLw()) {
455 startingWindow.mPolicyVisibility = false;
456 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700457 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -0700458
459 // We are becoming visible, so better freeze the screen with the windows that are
460 // getting visible so we also wait for them.
461 forAllWindows(mService::makeWindowFreezingScreenIfNeededLocked, true);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700462 }
463
464 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setVisibility: " + this
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200465 + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700466
467 if (changed) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800468 getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700469 if (performLayout) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700470 mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700471 false /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700472 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700473 }
Arthur Hung95b38a92018-07-20 18:56:12 +0800474 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700475 }
476 }
477
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200478 if (isReallyAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700479 delayed = true;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100480 } else {
481
482 // We aren't animating anything, but exiting windows rely on the animation finished
483 // callback being called in case the AppWindowToken was pretending to be animating,
484 // which we might have done because we were in closing/opening apps list.
485 onAnimationFinished();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700486 }
487
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700488 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100489 if ((mChildren.get(i)).isSelfOrChildAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700490 delayed = true;
491 }
492 }
493
494 if (visibilityChanged) {
495 if (visible && !delayed) {
496 // The token was made immediately visible, there will be no entrance animation.
497 // We need to inform the client the enter animation was finished.
498 mEnteringAnimation = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700499 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700500 }
Robert Carr61b81112017-07-17 18:08:15 -0700501
Jorim Jaggi110839b2018-01-22 12:49:04 +0100502 // If we're becoming visible, immediately change client visibility as well although it
503 // usually gets changed in AppWindowContainerController.setVisibility already. However,
504 // there seem to be some edge cases where we change our visibility but client visibility
505 // never gets updated.
506 // If we're becoming invisible, update the client visibility if we are not running an
507 // animation. Otherwise, we'll update client visibility in onAnimationFinished.
Jorim Jaggi3cad57f2018-02-20 18:32:01 +0100508 if (visible || !isReallyAnimating()) {
Jorim Jaggi110839b2018-01-22 12:49:04 +0100509 setClientHidden(!visible);
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100510 }
511
lumark588a3e82018-07-20 18:53:54 +0800512 if (!getDisplayContent().mClosingApps.contains(this)
513 && !getDisplayContent().mOpeningApps.contains(this)) {
chaviwa953fcf2018-03-01 12:00:39 -0800514 // The token is not closing nor opening, so even if there is an animation set, that
515 // doesn't mean that it goes through the normal app transition cycle so we have
516 // to inform the docked controller about visibility change.
517 // TODO(multi-display): notify docked divider on all displays where visibility was
518 // affected.
lumark588a3e82018-07-20 18:53:54 +0800519 getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged();
chaviwa953fcf2018-03-01 12:00:39 -0800520
521 // Take the screenshot before possibly hiding the WSA, otherwise the screenshot
522 // will not be taken.
523 mService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
524 }
525
Robert Carre7cc44d2017-03-20 19:04:30 -0700526 // If we are hidden but there is no delay needed we immediately
527 // apply the Surface transaction so that the ActivityManager
Robert Carr61b81112017-07-17 18:08:15 -0700528 // can have some guarantee on the Surface state following
529 // setting the visibility. This captures cases like dismissing
530 // the docked or pinned stack where there is no app transition.
531 //
532 // In the case of a "Null" animation, there will be
533 // no animation but there will still be a transition set.
534 // We still need to delay hiding the surface such that it
535 // can be synchronized with showing the next surface in the transition.
lumark588a3e82018-07-20 18:53:54 +0800536 if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) {
Robert Carr6914f082017-03-20 19:04:30 -0700537 SurfaceControl.openTransaction();
538 for (int i = mChildren.size() - 1; i >= 0; i--) {
539 mChildren.get(i).mWinAnimator.hide("immediately hidden");
540 }
541 SurfaceControl.closeTransaction();
542 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700543 }
544
545 return delayed;
546 }
547
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200548 /**
549 * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns
550 * true.
551 */
552 WindowState getTopFullscreenWindow() {
553 for (int i = mChildren.size() - 1; i >= 0; i--) {
554 final WindowState win = mChildren.get(i);
555 if (win != null && win.mAttrs.isFullscreen()) {
556 return win;
557 }
558 }
559 return null;
560 }
561
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800562 WindowState findMainWindow() {
Matthew Ng53e66b22018-01-12 17:13:13 -0800563 return findMainWindow(true);
564 }
565
566 /**
567 * Finds the main window that either has type base application or application starting if
568 * requested.
569 *
570 * @param includeStartingApp Allow to search application-starting windows to also be returned.
571 * @return The main window of type base application or application starting if requested.
572 */
573 WindowState findMainWindow(boolean includeStartingApp) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700574 WindowState candidate = null;
Matthew Ng53e66b22018-01-12 17:13:13 -0800575 for (int j = mChildren.size() - 1; j >= 0; --j) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700576 final WindowState win = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700577 final int type = win.mAttrs.type;
578 // No need to loop through child window as base application and starting types can't be
579 // child windows.
Matthew Ng53e66b22018-01-12 17:13:13 -0800580 if (type == TYPE_BASE_APPLICATION
581 || (includeStartingApp && type == TYPE_APPLICATION_STARTING)) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700582 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900583 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700584 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800585 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700586 candidate = win;
587 } else {
588 return win;
589 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800590 }
591 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700592 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800593 }
594
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800595 boolean windowsAreFocusable() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700596 return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800597 }
598
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800599 AppWindowContainerController getController() {
600 final WindowContainerController controller = super.getController();
601 return controller != null ? (AppWindowContainerController) controller : null;
602 }
603
Wale Ogunwale571771c2016-08-26 13:18:50 -0700604 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700605 boolean isVisible() {
Wale Ogunwalee471be62016-10-03 07:53:55 -0700606 // If the app token isn't hidden then it is considered visible and there is no need to check
607 // its children windows to see if they are visible.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200608 return !isHidden();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700609 }
610
611 @Override
Wale Ogunwalee287e192017-04-21 09:30:12 -0700612 void removeImmediately() {
613 onRemovedFromDisplay();
614 super.removeImmediately();
615 }
616
617 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700618 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800619 mIsExiting = false;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800620 removeAllWindowsIfPossible();
Bryce Lee6d410262017-02-28 15:30:17 -0800621 removeImmediately();
Craig Mautnere3119b72015-01-20 15:02:36 -0800622 }
623
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700624 @Override
625 boolean checkCompleteDeferredRemoval() {
626 if (mIsExiting) {
627 removeIfPossible();
628 }
629 return super.checkCompleteDeferredRemoval();
630 }
631
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700632 void onRemovedFromDisplay() {
Wale Ogunwalee287e192017-04-21 09:30:12 -0700633 if (mRemovingFromDisplay) {
634 return;
635 }
636 mRemovingFromDisplay = true;
637
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700638 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
639
Wale Ogunwale72919d22016-12-08 18:58:50 -0800640 boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700641
lumark588a3e82018-07-20 18:53:54 +0800642 getDisplayContent().mOpeningApps.remove(this);
643 getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
Jorim Jaggi10abe2f2017-01-03 16:44:46 +0100644 mService.mTaskSnapshotController.onAppRemoved(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700645 waitingToShow = false;
lumark588a3e82018-07-20 18:53:54 +0800646 if (getDisplayContent().mClosingApps.contains(this)) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700647 delayed = true;
lumark588a3e82018-07-20 18:53:54 +0800648 } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
649 getDisplayContent().mClosingApps.add(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700650 delayed = true;
651 }
652
653 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200654 + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700655
656 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
657 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
658
Jorim Jaggi19be6052017-08-03 18:33:43 +0200659 if (startingData != null && getController() != null) {
660 getController().removeStartingWindow();
661 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800662
Winson Chung87e5d552017-04-05 11:49:38 -0700663 // If this window was animating, then we need to ensure that the app transition notifies
lumark588a3e82018-07-20 18:53:54 +0800664 // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
665 // so add to that list now
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200666 if (isSelfAnimating()) {
lumark588a3e82018-07-20 18:53:54 +0800667 getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
Winson Chung87e5d552017-04-05 11:49:38 -0700668 }
669
Wale Ogunwalee287e192017-04-21 09:30:12 -0700670 final TaskStack stack = getStack();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700671 if (delayed && !isEmpty()) {
672 // set the token aside because it has an active animation to be finished
673 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
674 "removeAppToken make exiting: " + this);
Wale Ogunwalee287e192017-04-21 09:30:12 -0700675 if (stack != null) {
676 stack.mExitingAppTokens.add(this);
677 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700678 mIsExiting = true;
679 } else {
680 // Make sure there is no animation running on this token, so any windows associated
681 // with it will be removed as soon as their animations are complete
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200682 cancelAnimation();
Wale Ogunwale3106ae012017-05-16 08:56:37 -0700683 if (stack != null) {
684 stack.mExitingAppTokens.remove(this);
685 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700686 removeIfPossible();
687 }
688
689 removed = true;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700690 stopFreezingScreen(true, true);
Bryce Lee6d410262017-02-28 15:30:17 -0800691
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800692 final DisplayContent dc = getDisplayContent();
693 if (dc.mFocusedApp == this) {
694 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
695 + " displayId=" + dc.getDisplayId());
696 dc.setFocusedApp(null);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700697 mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700698 }
699
700 if (!delayed) {
701 updateReportedVisibilityLocked();
702 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700703
704 mRemovingFromDisplay = false;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700705 }
706
Chong Zhange05bcb12016-07-26 17:47:29 -0700707 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700708 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700709 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700710 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700711 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700712 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700713 if (wallpaperMightChange) {
714 requestUpdateWallpaperIfNeeded();
715 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700716 }
717
Robert Carre12aece2016-02-02 22:43:27 -0800718 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700719 destroySurfaces(false /*cleanupOnResume*/);
720 }
721
722 /**
723 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
724 * the client has finished with them.
725 *
726 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
727 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
728 * others so that they are ready to be reused. If set to false (common case), destroy all
729 * surfaces that's eligible, if the app is already stopped.
730 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700731 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700732 boolean destroyedSomething = false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100733
734 // Copying to a different list as multiple children can be removed.
Jorim Jaggi59f3e922018-01-05 15:40:32 +0100735 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100736 for (int i = children.size() - 1; i >= 0; i--) {
737 final WindowState win = children.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700738 destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
Robert Carre12aece2016-02-02 22:43:27 -0800739 }
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700740 if (destroyedSomething) {
741 final DisplayContent dc = getDisplayContent();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700742 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Adrian Roos23df3a32018-03-15 15:41:13 +0100743 updateLetterboxSurface(null);
Robert Carre12aece2016-02-02 22:43:27 -0800744 }
745 }
746
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800747 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700748 * Notify that the app is now resumed, and it was not stopped before, perform a clean
749 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800750 */
Jorim Jaggibae01b12017-04-11 16:29:10 -0700751 void notifyAppResumed(boolean wasStopped) {
Chong Zhangad24f962016-08-25 12:12:33 -0700752 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
Jorim Jaggibae01b12017-04-11 16:29:10 -0700753 + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700754 mAppStopped = false;
chaviwd3bf08d2017-08-01 17:24:59 -0700755 // Allow the window to turn the screen on once the app is resumed again.
756 setCanTurnScreenOn(true);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700757 if (!wasStopped) {
758 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800759 }
Robert Carre12aece2016-02-02 22:43:27 -0800760 }
761
Chong Zhangbef461f2015-10-27 11:38:24 -0700762 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700763 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
764 * keeping alive in case they were still being used.
765 */
766 void notifyAppStopped() {
767 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
768 mAppStopped = true;
769 destroySurfaces();
770 // Remove any starting window that was added for this app if they are still around.
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800771 if (getController() != null) {
772 getController().removeStartingWindow();
773 }
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700774 }
775
Chong Zhang92147042016-05-09 12:47:11 -0700776 void clearAllDrawn() {
777 allDrawn = false;
778 deferClearAllDrawn = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700779 }
780
Bryce Lee6d410262017-02-28 15:30:17 -0800781 Task getTask() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800782 return (Task) getParent();
Bryce Lee6d410262017-02-28 15:30:17 -0800783 }
784
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800785 TaskStack getStack() {
786 final Task task = getTask();
787 if (task != null) {
788 return task.mStack;
789 } else {
790 return null;
791 }
792 }
793
Bryce Lee6d410262017-02-28 15:30:17 -0800794 @Override
795 void onParentSet() {
796 super.onParentSet();
797
Robert Carred3e83b2017-04-21 13:26:55 -0700798 final Task task = getTask();
799
Bryce Lee6d410262017-02-28 15:30:17 -0800800 // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
801 // access visual elements like the {@link DisplayContent}. We must remove any associations
802 // such as animations.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800803 if (!mReparenting) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800804 if (task == null) {
805 // It is possible we have been marked as a closing app earlier. We must remove ourselves
806 // from this list so we do not participate in any future animations.
lumark588a3e82018-07-20 18:53:54 +0800807 getDisplayContent().mClosingApps.remove(this);
Robert Carred3e83b2017-04-21 13:26:55 -0700808 } else if (mLastParent != null && mLastParent.mStack != null) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800809 task.mStack.mExitingAppTokens.remove(this);
810 }
Bryce Lee6d410262017-02-28 15:30:17 -0800811 }
Jorim Jaggi6de61012018-03-19 14:53:23 +0100812 final TaskStack stack = getStack();
813
814 // If we reparent, make sure to remove ourselves from the old animation registry.
815 if (mAnimatingAppWindowTokenRegistry != null) {
816 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
817 }
818 mAnimatingAppWindowTokenRegistry = stack != null
819 ? stack.getAnimatingAppWindowTokenRegistry()
820 : null;
821
Robert Carred3e83b2017-04-21 13:26:55 -0700822 mLastParent = task;
Bryce Lee6d410262017-02-28 15:30:17 -0800823 }
824
Wale Ogunwalefa854eb2016-09-20 13:43:52 -0700825 void postWindowRemoveStartingWindowCleanup(WindowState win) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700826 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700827 if (startingWindow == win) {
828 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800829 if (getController() != null) {
830 getController().removeStartingWindow();
831 }
Wale Ogunwale6c459212017-05-17 08:56:03 -0700832 } else if (mChildren.size() == 0) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700833 // If this is the last window and we had requested a starting transition window,
834 // well there is no point now.
Jorim Jaggi02886a82016-12-06 09:10:06 -0800835 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700836 startingData = null;
Wale Ogunwale6c459212017-05-17 08:56:03 -0700837 if (mHiddenSetFromTransferredStartingWindow) {
838 // We set the hidden state to false for the token from a transferred starting window.
839 // We now reset it back to true since the starting window was the last window in the
840 // token.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200841 setHidden(true);
Wale Ogunwale6c459212017-05-17 08:56:03 -0700842 }
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100843 } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700844 // If this is the last window except for a starting transition window,
845 // we need to get rid of the starting transition.
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200846 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
847 + win);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800848 if (getController() != null) {
849 getController().removeStartingWindow();
850 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700851 }
852 }
853
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700854 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700855 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700856 WindowState win = mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800857 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700858 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700859 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800860 // Set mDestroying, we don't want any animation or delayed removal here.
861 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700862 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700863 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800864 }
865 }
866 }
867
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700868 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700869 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700870 // No need to loop through child windows as the answer should be the same as that of the
871 // parent window.
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700872 if (!(mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700873 return true;
874 }
875 }
876 return false;
877 }
878
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700879 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700880 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
881 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800882
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700883 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700884 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700885 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -0800886 }
Robert Carra1eb4392015-12-10 12:43:51 -0800887 }
888
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700889 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700890 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800891 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700892 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700893 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700894 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -0800895 }
896 }
897
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700898 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700899 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
900 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800901
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700902 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700903 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700904 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -0800905 }
906 }
907
Chong Zhang4d7369a2016-04-25 16:09:14 -0700908 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700909 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700910 final WindowState w = mChildren.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -0700911 w.requestUpdateWallpaperIfNeeded();
912 }
913 }
914
Chong Zhangd78ddb42016-03-02 17:01:14 -0800915 boolean isRelaunching() {
916 return mPendingRelaunchCount > 0;
917 }
918
Robert Carr68375192017-06-13 12:41:53 -0700919 boolean shouldFreezeBounds() {
920 final Task task = getTask();
921
922 // For freeform windows, we can't freeze the bounds at the moment because this would make
923 // the resizing unresponsive.
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700924 if (task == null || task.inFreeformWindowingMode()) {
Robert Carr68375192017-06-13 12:41:53 -0700925 return false;
926 }
927
928 // We freeze the bounds while drag resizing to deal with the time between
929 // the divider/drag handle being released, and the handling it's new
930 // configuration. If we are relaunched outside of the drag resizing state,
931 // we need to be careful not to do this.
932 return getTask().isDragResizing();
933 }
934
Chong Zhangd78ddb42016-03-02 17:01:14 -0800935 void startRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -0700936 if (shouldFreezeBounds()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -0800937 freezeBounds();
938 }
Robert Carrd5c7dd62017-03-08 10:39:30 -0800939
940 // In the process of tearing down before relaunching, the app will
941 // try and clean up it's child surfaces. We need to prevent this from
942 // happening, so we sever the children, transfering their ownership
943 // from the client it-self to the parent surface (owned by us).
Robert Carr29daa922018-04-27 11:56:48 -0700944 detachChildren();
945
946 mPendingRelaunchCount++;
947 }
948
949 void detachChildren() {
Robert Carrfd8e93b2018-05-10 13:40:25 -0700950 SurfaceControl.openTransaction();
Robert Carrd5c7dd62017-03-08 10:39:30 -0800951 for (int i = mChildren.size() - 1; i >= 0; i--) {
952 final WindowState w = mChildren.get(i);
953 w.mWinAnimator.detachChildren();
954 }
Robert Carrfd8e93b2018-05-10 13:40:25 -0700955 SurfaceControl.closeTransaction();
Chong Zhangd78ddb42016-03-02 17:01:14 -0800956 }
957
958 void finishRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -0700959 unfreezeBounds();
960
Chong Zhangd78ddb42016-03-02 17:01:14 -0800961 if (mPendingRelaunchCount > 0) {
962 mPendingRelaunchCount--;
Bryce Lee081554b2017-05-25 07:52:12 -0700963 } else {
964 // Update keyguard flags upon finishing relaunch.
965 checkKeyguardFlagsChanged();
Chong Zhangd78ddb42016-03-02 17:01:14 -0800966 }
967 }
968
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700969 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700970 if (mPendingRelaunchCount == 0) {
971 return;
972 }
Robert Carr68375192017-06-13 12:41:53 -0700973 unfreezeBounds();
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700974 mPendingRelaunchCount = 0;
975 }
976
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700977 /**
978 * Returns true if the new child window we are adding to this token is considered greater than
979 * the existing child window in this token in terms of z-order.
980 */
981 @Override
982 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
983 WindowState existingWindow) {
984 final int type1 = newWindow.mAttrs.type;
985 final int type2 = existingWindow.mAttrs.type;
986
987 // Base application windows should be z-ordered BELOW all other windows in the app token.
988 if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
989 return false;
990 } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
991 return true;
992 }
993
994 // Starting windows should be z-ordered ABOVE all other windows in the app token.
995 if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
996 return true;
997 } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
998 return false;
999 }
1000
1001 // Otherwise the new window is greater than the existing window.
1002 return true;
1003 }
1004
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001005 @Override
Robert Carra1eb4392015-12-10 12:43:51 -08001006 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001007 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001008
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001009 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001010 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001011 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001012 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
1013 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001014
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001015 // if we got a replacement window, reset the timeout to give drawing more time
1016 if (gotReplacementWindow) {
1017 mService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -08001018 }
Jorim Jaggife762342016-10-13 14:33:27 +02001019 checkKeyguardFlagsChanged();
1020 }
1021
1022 @Override
1023 void removeChild(WindowState child) {
1024 super.removeChild(child);
1025 checkKeyguardFlagsChanged();
Adrian Roos23df3a32018-03-15 15:41:13 +01001026 updateLetterboxSurface(child);
Robert Carra1eb4392015-12-10 12:43:51 -08001027 }
1028
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001029 private boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001030 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001031 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001032 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -08001033 return true;
1034 }
1035 }
1036 return false;
1037 }
1038
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001039 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001040 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001041 (mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -08001042 }
1043 }
1044
Winson Chung30480042017-01-26 10:55:34 -08001045 void reparent(Task task, int position) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001046 final Task currentTask = getTask();
1047 if (task == currentTask) {
Winson Chung30480042017-01-26 10:55:34 -08001048 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001049 "window token=" + this + " already child of task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001050 }
Bryce Lee6d410262017-02-28 15:30:17 -08001051
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001052 if (currentTask.mStack != task.mStack) {
Bryce Lee6d410262017-02-28 15:30:17 -08001053 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001054 "window token=" + this + " current task=" + currentTask
Bryce Lee6d410262017-02-28 15:30:17 -08001055 + " belongs to a different stack than " + task);
1056 }
1057
Winson Chung30480042017-01-26 10:55:34 -08001058 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001059 + " from task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001060 final DisplayContent prevDisplayContent = getDisplayContent();
1061
Bryce Lee6d410262017-02-28 15:30:17 -08001062 mReparenting = true;
1063
Winson Chung30480042017-01-26 10:55:34 -08001064 getParent().removeChild(this);
1065 task.addChild(this, position);
1066
Bryce Lee6d410262017-02-28 15:30:17 -08001067 mReparenting = false;
1068
Winson Chung30480042017-01-26 10:55:34 -08001069 // Relayout display(s).
1070 final DisplayContent displayContent = task.getDisplayContent();
1071 displayContent.setLayoutNeeded();
1072 if (prevDisplayContent != displayContent) {
1073 onDisplayChanged(displayContent);
1074 prevDisplayContent.setLayoutNeeded();
1075 }
1076 }
1077
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001078 @Override
1079 void onDisplayChanged(DisplayContent dc) {
1080 DisplayContent prevDc = mDisplayContent;
1081 super.onDisplayChanged(dc);
1082 if (prevDc != null && prevDc.mFocusedApp == this) {
1083 prevDc.setFocusedApp(null);
lumarkbf844642018-11-23 17:11:36 +08001084 final TaskStack stack = dc.getTopStack();
1085 if (stack != null) {
1086 final Task task = stack.getTopChild();
1087 if (task != null && task.getTopChild() == this) {
1088 dc.setFocusedApp(this);
1089 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001090 }
1091 }
1092 }
1093
Jorim Jaggi0429f352015-12-22 16:29:16 +01001094 /**
1095 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
1096 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
1097 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
1098 * with a queue.
1099 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001100 private void freezeBounds() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001101 final Task task = getTask();
1102 mFrozenBounds.offer(new Rect(task.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001103
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001104 if (task.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001105 // We didn't call prepareFreezingBounds on the task, so use the current value.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001106 mFrozenMergedConfig.offer(new Configuration(task.getConfiguration()));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001107 } else {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001108 mFrozenMergedConfig.offer(new Configuration(task.mPreparedFrozenMergedConfig));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001109 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001110 // Calling unset() to make it equal to Configuration.EMPTY.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001111 task.mPreparedFrozenMergedConfig.unset();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001112 }
1113
1114 /**
1115 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
1116 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001117 private void unfreezeBounds() {
Robert Carr68375192017-06-13 12:41:53 -07001118 if (mFrozenBounds.isEmpty()) {
1119 return;
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001120 }
Robert Carr68375192017-06-13 12:41:53 -07001121 mFrozenBounds.remove();
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001122 if (!mFrozenMergedConfig.isEmpty()) {
1123 mFrozenMergedConfig.remove();
1124 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001125 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001126 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001127 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +01001128 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001129 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001130 }
1131
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001132 void setAppLayoutChanges(int changes, String reason) {
1133 if (!mChildren.isEmpty()) {
1134 final DisplayContent dc = getDisplayContent();
1135 dc.pendingLayoutChanges |= changes;
1136 if (DEBUG_LAYOUT_REPEATS) {
1137 mService.mWindowPlacerLocked.debugLayoutRepeats(reason, dc.pendingLayoutChanges);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001138 }
1139 }
1140 }
1141
1142 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001143 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001144 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001145 if (win.removeReplacedWindowIfNeeded(replacement)) {
1146 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001147 }
1148 }
1149 }
1150
1151 void startFreezingScreen() {
1152 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001153 + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001154 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001155 if (!hiddenRequested) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001156 if (!mFreezingScreen) {
1157 mFreezingScreen = true;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001158 mService.registerAppFreezeListener(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001159 mService.mAppsFreezingScreen++;
1160 if (mService.mAppsFreezingScreen == 1) {
Robert Carrae606b42018-02-15 15:36:23 -08001161 mService.startFreezingDisplayLocked(0, 0, getDisplayContent());
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001162 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1163 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001164 }
1165 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001166 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001167 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001168 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001169 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001170 }
1171 }
1172 }
1173
1174 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001175 if (!mFreezingScreen) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001176 return;
1177 }
1178 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001179 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001180 boolean unfrozeWindows = false;
1181 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001182 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001183 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001184 }
1185 if (force || unfrozeWindows) {
1186 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001187 mFreezingScreen = false;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001188 mService.unregisterAppFreezeListener(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001189 mService.mAppsFreezingScreen--;
1190 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001191 }
1192 if (unfreezeSurfaceNow) {
1193 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001194 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001195 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001196 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001197 }
1198 }
1199
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001200 @Override
1201 public void onAppFreezeTimeout() {
1202 Slog.w(TAG_WM, "Force clearing freeze: " + this);
1203 stopFreezingScreen(true, true);
1204 }
1205
Jorim Jaggi60f9c972018-02-01 19:21:07 +01001206 /**
1207 * Tries to transfer the starting window from a token that's above ourselves in the task but
1208 * not visible anymore. This is a common scenario apps use: Trampoline activity T start main
1209 * activity M in the same task. Now, when reopening the task, T starts on top of M but then
1210 * immediately finishes after, so we have to transfer T to M.
1211 */
1212 void transferStartingWindowFromHiddenAboveTokenIfNeeded() {
1213 final Task task = getTask();
1214 for (int i = task.mChildren.size() - 1; i >= 0; i--) {
1215 final AppWindowToken fromToken = task.mChildren.get(i);
1216 if (fromToken == this) {
1217 return;
1218 }
1219 if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) {
1220 return;
1221 }
1222 }
1223 }
1224
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001225 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001226 final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001227 if (fromToken == null) {
1228 return false;
1229 }
1230
1231 final WindowState tStartingWindow = fromToken.startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001232 if (tStartingWindow != null && fromToken.startingSurface != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001233 // In this case, the starting icon has already been displayed, so start
1234 // letting windows get shown immediately without any more transitions.
lumark588a3e82018-07-20 18:53:54 +08001235 getDisplayContent().mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001236
1237 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1238 + " from " + fromToken + " to " + this);
1239
1240 final long origId = Binder.clearCallingIdentity();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001241 try {
1242 // Transfer the starting window over to the new token.
1243 startingData = fromToken.startingData;
1244 startingSurface = fromToken.startingSurface;
1245 startingDisplayed = fromToken.startingDisplayed;
1246 fromToken.startingDisplayed = false;
1247 startingWindow = tStartingWindow;
1248 reportedVisible = fromToken.reportedVisible;
1249 fromToken.startingData = null;
1250 fromToken.startingSurface = null;
1251 fromToken.startingWindow = null;
1252 fromToken.startingMoved = true;
1253 tStartingWindow.mToken = this;
1254 tStartingWindow.mAppToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001255
Peter Visontay3556a3b2017-11-01 17:23:17 +00001256 if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1257 "Removing starting " + tStartingWindow + " from " + fromToken);
1258 fromToken.removeChild(tStartingWindow);
1259 fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
1260 fromToken.mHiddenSetFromTransferredStartingWindow = false;
1261 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001262
Peter Visontay3556a3b2017-11-01 17:23:17 +00001263 // Propagate other interesting state between the tokens. If the old token is displayed,
1264 // we should immediately force the new one to be displayed. If it is animating, we need
1265 // to move that animation to the new one.
1266 if (fromToken.allDrawn) {
1267 allDrawn = true;
1268 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1269 }
1270 if (fromToken.firstWindowDrawn) {
1271 firstWindowDrawn = true;
1272 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001273 if (!fromToken.isHidden()) {
1274 setHidden(false);
Peter Visontay3556a3b2017-11-01 17:23:17 +00001275 hiddenRequested = false;
1276 mHiddenSetFromTransferredStartingWindow = true;
1277 }
1278 setClientHidden(fromToken.mClientHidden);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001279
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001280 transferAnimation(fromToken);
1281
1282 // When transferring an animation, we no longer need to apply an animation to the
1283 // the token we transfer the animation over. Thus, remove the animation from
1284 // pending opening apps.
lumark588a3e82018-07-20 18:53:54 +08001285 getDisplayContent().mOpeningApps.remove(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001286
Peter Visontay3556a3b2017-11-01 17:23:17 +00001287 mService.updateFocusedWindowLocked(
1288 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
1289 getDisplayContent().setLayoutNeeded();
1290 mService.mWindowPlacerLocked.performSurfacePlacement();
1291 } finally {
1292 Binder.restoreCallingIdentity(origId);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001293 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001294 return true;
1295 } else if (fromToken.startingData != null) {
1296 // The previous app was getting ready to show a
1297 // starting window, but hasn't yet done so. Steal it!
1298 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1299 "Moving pending starting from " + fromToken + " to " + this);
1300 startingData = fromToken.startingData;
1301 fromToken.startingData = null;
1302 fromToken.startingMoved = true;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001303 if (getController() != null) {
1304 getController().scheduleAddStartingWindow();
1305 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001306 return true;
1307 }
1308
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001309 // TODO: Transfer thumbnail
1310
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001311 return false;
1312 }
1313
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001314 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001315 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001316 }
1317
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001318 @Override
1319 void onAppTransitionDone() {
1320 sendingToBottom = false;
1321 }
1322
Wale Ogunwale51362492016-09-08 17:49:17 -07001323 /**
1324 * We override because this class doesn't want its children affecting its reported orientation
1325 * in anyway.
1326 */
1327 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001328 int getOrientation(int candidate) {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001329 if (candidate == SCREEN_ORIENTATION_BEHIND) {
1330 // Allow app to specify orientation regardless of its visibility state if the current
1331 // candidate want us to use orientation behind. I.e. the visible app on-top of this one
1332 // wants us to use the orientation of the app behind it.
1333 return mOrientation;
1334 }
1335
Bryce Lee61fbcbc2017-03-10 14:14:03 -08001336 // The {@link AppWindowToken} should only specify an orientation when it is not closing or
1337 // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
1338 // an Activity in another task being started in the wrong orientation during the transition.
lumark588a3e82018-07-20 18:53:54 +08001339 if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
1340 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
Bryce Leea163b762017-01-24 11:05:01 -08001341 return mOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07001342 }
Bryce Leea163b762017-01-24 11:05:01 -08001343
1344 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001345 }
1346
Wale Ogunwaleb198b742016-12-01 08:44:09 -08001347 /** Returns the app's preferred orientation regardless of its currently visibility state. */
1348 int getOrientationIgnoreVisibility() {
1349 return mOrientation;
1350 }
1351
Craig Mautnerdbb79912012-03-01 18:59:14 -08001352 @Override
Winson Chunge55c0192017-08-24 14:50:48 -07001353 public void onConfigurationChanged(Configuration newParentConfig) {
1354 final int prevWinMode = getWindowingMode();
1355 super.onConfigurationChanged(newParentConfig);
1356 final int winMode = getWindowingMode();
1357
1358 if (prevWinMode == winMode) {
1359 return;
1360 }
1361
1362 if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) {
1363 // Entering PiP from fullscreen, reset the snap fraction
1364 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
Winson Chung82267ce2018-04-06 16:38:26 -07001365 } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED
1366 && !isHidden()) {
Winson Chunge55c0192017-08-24 14:50:48 -07001367 // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
1368 // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
1369 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
1370 if (pinnedStack != null) {
Winson Chung8efa1652018-06-06 09:34:23 -07001371 final Rect stackBounds;
1372 if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
1373 // We are animating the bounds, use the pre-animation bounds to save the snap
1374 // fraction
1375 stackBounds = pinnedStack.mPreAnimationBounds;
1376 } else {
1377 // We skip the animation if the fullscreen configuration is not compatible, so
1378 // use the current bounds to calculate the saved snap fraction instead
1379 // (see PinnedActivityStack.skipResizeAnimation())
1380 stackBounds = mTmpRect;
1381 pinnedStack.getBounds(stackBounds);
1382 }
Winson Chunge55c0192017-08-24 14:50:48 -07001383 mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
Winson Chung8efa1652018-06-06 09:34:23 -07001384 stackBounds);
Winson Chunge55c0192017-08-24 14:50:48 -07001385 }
1386 }
1387 }
1388
1389 @Override
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001390 void checkAppWindowsReadyToShow() {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001391 if (allDrawn == mLastAllDrawn) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001392 return;
1393 }
1394
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001395 mLastAllDrawn = allDrawn;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001396 if (!allDrawn) {
1397 return;
1398 }
1399
1400 // The token has now changed state to having all windows shown... what to do, what to do?
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001401 if (mFreezingScreen) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001402 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001403 stopFreezingScreen(false, true);
1404 if (DEBUG_ORIENTATION) Slog.i(TAG,
1405 "Setting mOrientationChangeComplete=true because wtoken " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001406 + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001407 // This will set mOrientationChangeComplete and cause a pass through layout.
1408 setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001409 "checkAppWindowsReadyToShow: freezingScreen");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001410 } else {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001411 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001412
1413 // We can now show all of the drawn windows!
lumark588a3e82018-07-20 18:53:54 +08001414 if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001415 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001416 }
1417 }
1418 }
1419
Matthew Ng5d23afa2017-06-21 16:16:24 -07001420 /**
Bryce Leed390deb2017-06-22 13:14:28 -07001421 * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
1422 * child {@link WindowState}. A child is considered if it has been passed into
1423 * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
1424 * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
1425 * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
1426 *
1427 * @return {@code true} If all children have been considered, {@code false}.
1428 */
1429 private boolean allDrawnStatesConsidered() {
Bryce Lee6311c4b2017-07-06 14:09:29 -07001430 for (int i = mChildren.size() - 1; i >= 0; --i) {
1431 final WindowState child = mChildren.get(i);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001432 if (child.mightAffectAllDrawn() && !child.getDrawnStateEvaluated()) {
Bryce Leed390deb2017-06-22 13:14:28 -07001433 return false;
1434 }
1435 }
1436 return true;
1437 }
1438
1439 /**
Matthew Ng5d23afa2017-06-21 16:16:24 -07001440 * Determines if the token has finished drawing. This should only be called from
1441 * {@link DisplayContent#applySurfaceChangesTransaction}
1442 */
Matthew Ng498c71d2017-04-18 13:55:45 -07001443 void updateAllDrawn() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001444 if (!allDrawn) {
Matthew Ng498c71d2017-04-18 13:55:45 -07001445 // Number of drawn windows can be less when a window is being relaunched, wait for
Bryce Leed390deb2017-06-22 13:14:28 -07001446 // all windows to be launched and drawn for this token be considered all drawn.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001447 final int numInteresting = mNumInterestingWindows;
Bryce Leed390deb2017-06-22 13:14:28 -07001448
1449 // We must make sure that all present children have been considered (determined by
1450 // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
1451 // drawn.
1452 if (numInteresting > 0 && allDrawnStatesConsidered()
1453 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001454 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001455 + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001456 allDrawn = true;
1457 // Force an additional layout pass where
1458 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
Matthew Ng498c71d2017-04-18 13:55:45 -07001459 if (mDisplayContent != null) {
1460 mDisplayContent.setLayoutNeeded();
1461 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001462 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Robert Carrecc06b32017-04-18 14:25:10 -07001463
Winson Chunge7ba6862017-05-24 12:13:33 -07001464 // Notify the pinned stack upon all windows drawn. If there was an animation in
1465 // progress then this signal will resume that animation.
Wale Ogunwale61911492017-10-11 08:50:50 -07001466 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
Winson Chunge7ba6862017-05-24 12:13:33 -07001467 if (pinnedStack != null) {
1468 pinnedStack.onAllWindowsDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -07001469 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001470 }
1471 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001472 }
1473
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001474 /**
1475 * Updated this app token tracking states for interesting and drawn windows based on the window.
1476 *
1477 * @return Returns true if the input window is considered interesting and drawn while all the
1478 * windows in this app token where not considered drawn as of the last pass.
1479 */
1480 boolean updateDrawnWindowStates(WindowState w) {
Bryce Leed390deb2017-06-22 13:14:28 -07001481 w.setDrawnStateEvaluated(true /*evaluated*/);
1482
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001483 if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001484 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001485 + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001486 }
1487
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001488 if (allDrawn && !mFreezingScreen) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001489 return false;
1490 }
1491
1492 if (mLastTransactionSequence != mService.mTransactionSequence) {
1493 mLastTransactionSequence = mService.mTransactionSequence;
Matthew Ng53e66b22018-01-12 17:13:13 -08001494 mNumDrawnWindows = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001495 startingDisplayed = false;
Matthew Ng53e66b22018-01-12 17:13:13 -08001496
1497 // There is the main base application window, even if it is exiting, wait for it
1498 mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001499 }
1500
1501 final WindowStateAnimator winAnimator = w.mWinAnimator;
1502
1503 boolean isInterestingAndDrawn = false;
1504
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001505 if (!allDrawn && w.mightAffectAllDrawn()) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001506 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1507 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001508 + ", isAnimationSet=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001509 if (!w.isDrawnLw()) {
1510 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
1511 + " pv=" + w.mPolicyVisibility
1512 + " mDrawState=" + winAnimator.drawStateToString()
1513 + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001514 + " a=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001515 }
1516 }
1517
1518 if (w != startingWindow) {
1519 if (w.isInteresting()) {
Matthew Ng53e66b22018-01-12 17:13:13 -08001520 // Add non-main window as interesting since the main app has already been added
1521 if (findMainWindow(false /* includeStartingApp */) != w) {
1522 mNumInterestingWindows++;
1523 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001524 if (w.isDrawnLw()) {
1525 mNumDrawnWindows++;
1526
1527 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
1528 + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001529 + " freezingScreen=" + mFreezingScreen
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001530 + " mAppFreezing=" + w.mAppFreezing);
1531
1532 isInterestingAndDrawn = true;
1533 }
1534 }
1535 } else if (w.isDrawnLw()) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001536 if (getController() != null) {
1537 getController().reportStartingWindowDrawn();
1538 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001539 startingDisplayed = true;
1540 }
1541 }
1542
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001543 return isInterestingAndDrawn;
1544 }
1545
Adrian Roos23df3a32018-03-15 15:41:13 +01001546 void layoutLetterbox(WindowState winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001547 final WindowState w = findMainWindow();
Adrian Roosf93b6d22018-03-21 13:48:26 +01001548 if (w == null || winHint != null && w != winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001549 return;
1550 }
Jorim Jaggia32da382018-03-28 18:01:22 +02001551 final boolean surfaceReady = w.isDrawnLw() // Regular case
Adrian Roosf93b6d22018-03-21 13:48:26 +01001552 || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
1553 || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
1554 final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001555 if (needsLetterbox) {
1556 if (mLetterbox == null) {
1557 mLetterbox = new Letterbox(() -> makeChildSurface(null));
1558 }
chaviw492139a2018-07-16 16:07:35 -07001559 mLetterbox.layout(getParent().getBounds(), w.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001560 } else if (mLetterbox != null) {
Adrian Roos23df3a32018-03-15 15:41:13 +01001561 mLetterbox.hide();
1562 }
1563 }
1564
1565 void updateLetterboxSurface(WindowState winHint) {
1566 final WindowState w = findMainWindow();
1567 if (w != winHint && winHint != null && w != null) {
1568 return;
1569 }
1570 layoutLetterbox(winHint);
1571 if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
1572 mLetterbox.applySurfaceChanges(mPendingTransaction);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001573 }
1574 }
1575
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001576 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001577 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001578 // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
1579 // before the non-exiting app tokens. So, we skip the exiting app tokens here.
1580 // TODO: Investigate if we need to continue to do this or if we can just process them
1581 // in-order.
1582 if (mIsExiting && !waitingForReplacement()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001583 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001584 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001585 return forAllWindowsUnchecked(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001586 }
1587
lumark588a3e82018-07-20 18:53:54 +08001588 @Override
1589 void forAllAppWindows(Consumer<AppWindowToken> callback) {
1590 callback.accept(this);
1591 }
1592
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001593 boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
1594 boolean traverseTopToBottom) {
1595 return super.forAllWindows(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001596 }
1597
1598 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001599 AppWindowToken asAppWindowToken() {
1600 // I am an app window token!
1601 return this;
1602 }
1603
1604 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07001605 boolean fillsParent() {
1606 return mFillsParent;
1607 }
1608
1609 void setFillsParent(boolean fillsParent) {
1610 mFillsParent = fillsParent;
1611 }
1612
Jorim Jaggife762342016-10-13 14:33:27 +02001613 boolean containsDismissKeyguardWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07001614 // Window state is transient during relaunch. We are not guaranteed to be frozen during the
1615 // entirety of the relaunch.
1616 if (isRelaunching()) {
1617 return mLastContainsDismissKeyguardWindow;
1618 }
1619
Jorim Jaggife762342016-10-13 14:33:27 +02001620 for (int i = mChildren.size() - 1; i >= 0; i--) {
1621 if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
1622 return true;
1623 }
1624 }
1625 return false;
1626 }
1627
1628 boolean containsShowWhenLockedWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07001629 // When we are relaunching, it is possible for us to be unfrozen before our previous
1630 // windows have been added back. Using the cached value ensures that our previous
1631 // showWhenLocked preference is honored until relaunching is complete.
1632 if (isRelaunching()) {
1633 return mLastContainsShowWhenLockedWindow;
1634 }
1635
Jorim Jaggife762342016-10-13 14:33:27 +02001636 for (int i = mChildren.size() - 1; i >= 0; i--) {
1637 if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
1638 return true;
1639 }
1640 }
Bryce Lee081554b2017-05-25 07:52:12 -07001641
Jorim Jaggife762342016-10-13 14:33:27 +02001642 return false;
1643 }
1644
1645 void checkKeyguardFlagsChanged() {
1646 final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
1647 final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
1648 if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
1649 || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
lumark588a3e82018-07-20 18:53:54 +08001650 mService.notifyKeyguardFlagsChanged(null /* callback */,
1651 getDisplayContent().getDisplayId());
Jorim Jaggife762342016-10-13 14:33:27 +02001652 }
1653 mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
1654 mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
1655 }
1656
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001657 WindowState getImeTargetBelowWindow(WindowState w) {
1658 final int index = mChildren.indexOf(w);
1659 if (index > 0) {
1660 final WindowState target = mChildren.get(index - 1);
1661 if (target.canBeImeTarget()) {
1662 return target;
1663 }
1664 }
1665 return null;
1666 }
1667
1668 WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
1669 WindowState candidate = null;
1670 for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
1671 final WindowState w = mChildren.get(i);
1672 if (w.mRemoved) {
1673 continue;
1674 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02001675 if (candidate == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00001676 candidate = w;
1677 }
1678 }
1679 return candidate;
1680 }
1681
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001682 /**
1683 * See {@link Activity#setDisablePreviewScreenshots}.
1684 */
1685 void setDisablePreviewScreenshots(boolean disable) {
Wale Ogunwale6c459212017-05-17 08:56:03 -07001686 mDisablePreviewScreenshots = disable;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01001687 }
1688
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001689 /**
chaviwd3bf08d2017-08-01 17:24:59 -07001690 * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
1691 */
1692 void setCanTurnScreenOn(boolean canTurnScreenOn) {
1693 mCanTurnScreenOn = canTurnScreenOn;
1694 }
1695
1696 /**
1697 * Indicates whether the current launch can turn the screen on. This is to prevent multiple
1698 * relayouts from turning the screen back on. The screen should only turn on at most
1699 * once per activity resume.
1700 *
1701 * @return true if the screen can be turned on.
1702 */
1703 boolean canTurnScreenOn() {
1704 return mCanTurnScreenOn;
1705 }
1706
1707 /**
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001708 * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
1709 * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
1710 * we can't take a snapshot for other reasons, for example, if we have a secure window.
1711 *
1712 * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
1713 * screenshot.
1714 */
1715 boolean shouldUseAppThemeSnapshot() {
Wale Ogunwale6c459212017-05-17 08:56:03 -07001716 return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
Jorim Jaggid635a4a2017-05-03 15:21:26 +02001717 true /* topToBottom */);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01001718 }
1719
Jorim Jaggibe418292018-03-26 16:14:12 +02001720 SurfaceControl getAppAnimationLayer() {
Jorim Jaggi391790622018-04-18 15:30:44 +02001721 return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
1722 : needsZBoost() ? ANIMATION_LAYER_BOOSTED
1723 : ANIMATION_LAYER_STANDARD);
Jorim Jaggibe418292018-03-26 16:14:12 +02001724 }
1725
chaviw23ee71c2017-12-18 11:29:41 -08001726 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +01001727 public SurfaceControl getAnimationLeashParent() {
Robert Carrb9506032018-02-13 13:54:00 -08001728 // All normal app transitions take place in an animation layer which is below the pinned
1729 // stack but may be above the parent stacks of the given animating apps.
1730 // For transitions in the pinned stack (menu activity) we just let them occur as a child
1731 // of the pinned stack.
1732 if (!inPinnedWindowingMode()) {
1733 return getAppAnimationLayer();
1734 } else {
1735 return getStack().getSurfaceControl();
1736 }
chaviw23ee71c2017-12-18 11:29:41 -08001737 }
1738
Jorim Jaggic6976f02018-04-18 16:31:07 +02001739 private boolean shouldAnimate(int transit) {
1740 final boolean isSplitScreenPrimary =
1741 getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
1742 final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
1743
1744 // We animate always if it's not split screen primary, and only some special cases in split
1745 // screen primary because it causes issues with stack clipping when we run an un-minimize
1746 // animation at the same time.
1747 return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
1748 }
1749
Vishnu Naira2977262018-07-26 13:31:26 -07001750 /**
1751 * Creates a layer to apply crop to an animation.
1752 */
1753 private SurfaceControl createAnimationBoundsLayer(Transaction t) {
1754 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
1755 final SurfaceControl.Builder builder = makeAnimationLeash()
1756 .setParent(getAnimationLeashParent())
1757 .setName(getSurfaceControl() + " - animation-bounds")
1758 .setSize(getSurfaceWidth(), getSurfaceHeight());
1759 final SurfaceControl boundsLayer = builder.build();
Vishnu Naird454442d2018-11-13 13:51:01 -08001760 t.setWindowCrop(boundsLayer, getSurfaceWidth(), getSurfaceHeight());
Vishnu Naira2977262018-07-26 13:31:26 -07001761 t.show(boundsLayer);
1762 return boundsLayer;
1763 }
1764
Riddle Hsua118b3a2018-10-11 22:05:06 +08001765 /** Get position and crop region of animation. */
1766 @VisibleForTesting
1767 void getAnimationBounds(Point outPosition, Rect outBounds) {
1768 outPosition.set(0, 0);
1769 outBounds.setEmpty();
1770
1771 final TaskStack stack = getStack();
1772 final Task task = getTask();
1773 if (task != null && task.inFreeformWindowingMode()) {
1774 task.getRelativePosition(outPosition);
1775 } else if (stack != null) {
1776 stack.getRelativePosition(outPosition);
1777 }
1778
1779 // Always use stack bounds in order to have the ability to animate outside the task region.
1780 // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
1781 // according to the bounds.
1782 if (stack != null) {
1783 stack.getBounds(outBounds);
1784 }
1785 // We have the relative position so the local position can be removed from bounds.
1786 outBounds.offsetTo(0, 0);
1787 }
1788
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001789 boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
1790 boolean isVoiceInteraction) {
1791
Jorim Jaggic6976f02018-04-18 16:31:07 +02001792 if (mService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001793 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Jorim Jaggic6976f02018-04-18 16:31:07 +02001794 Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
1795 + " atoken=" + this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001796 }
1797 cancelAnimation();
1798 return false;
1799 }
1800
1801 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
1802 // to animate and it can cause strange artifacts when we unfreeze the display if some
1803 // different animation is running.
1804 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
1805 if (okToAnimate()) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001806 final AnimationAdapter adapter;
Riddle Hsua118b3a2018-10-11 22:05:06 +08001807 getAnimationBounds(mTmpPoint, mTmpRect);
Jorim Jaggic4d29f22018-03-22 16:30:56 +01001808
1809 // Delaying animation start isn't compatible with remote animations at all.
lumark588a3e82018-07-20 18:53:54 +08001810 if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
Jorim Jaggic4d29f22018-03-22 16:30:56 +01001811 && !mSurfaceAnimator.isAnimationStartDelayed()) {
lumark588a3e82018-07-20 18:53:54 +08001812 adapter = getDisplayContent().mAppTransition.getRemoteAnimationController()
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001813 .createAnimationAdapter(this, mTmpPoint, mTmpRect);
1814 } else {
lumark588a3e82018-07-20 18:53:54 +08001815 final int appStackClipMode =
1816 getDisplayContent().mAppTransition.getAppStackClipMode();
Vishnu Naira2977262018-07-26 13:31:26 -07001817 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
1818
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001819 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
1820 if (a != null) {
1821 adapter = new LocalAnimationAdapter(
1822 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
lumark588a3e82018-07-20 18:53:54 +08001823 getDisplayContent().mAppTransition.canSkipFirstFrame(),
Vishnu Naira2977262018-07-26 13:31:26 -07001824 appStackClipMode,
Jorim Jaggiaa763cd2018-03-22 23:20:36 +01001825 true /* isAppAnimation */),
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001826 mService.mSurfaceAnimationRunner);
1827 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
1828 mNeedsZBoost = true;
1829 }
1830 mTransit = transit;
lumark588a3e82018-07-20 18:53:54 +08001831 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001832 } else {
1833 adapter = null;
chaviw23ee71c2017-12-18 11:29:41 -08001834 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001835 }
1836 if (adapter != null) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001837 startAnimation(getPendingTransaction(), adapter, !isVisible());
Jorim Jaggi82c17862018-02-21 17:50:18 +01001838 if (adapter.getShowWallpaper()) {
1839 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1840 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001841 }
1842 } else {
1843 cancelAnimation();
1844 }
1845 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
1846
1847 return isReallyAnimating();
1848 }
1849
1850 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
1851 boolean isVoiceInteraction) {
1852 final DisplayContent displayContent = getTask().getDisplayContent();
1853 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1854 final int width = displayInfo.appWidth;
1855 final int height = displayInfo.appHeight;
1856 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
1857 "applyAnimation: atoken=" + this);
1858
1859 // Determine the visible rect to calculate the thumbnail clip
1860 final WindowState win = findMainWindow();
1861 final Rect frame = new Rect(0, 0, width, height);
1862 final Rect displayFrame = new Rect(0, 0,
1863 displayInfo.logicalWidth, displayInfo.logicalHeight);
1864 final Rect insets = new Rect();
1865 final Rect stableInsets = new Rect();
1866 Rect surfaceInsets = null;
1867 final boolean freeform = win != null && win.inFreeformWindowingMode();
1868 if (win != null) {
1869 // Containing frame will usually cover the whole screen, including dialog windows.
1870 // For freeform workspace windows it will not cover the whole screen and it also
1871 // won't exactly match the final freeform window frame (e.g. when overlapping with
1872 // the status bar). In that case we need to use the final frame.
1873 if (freeform) {
chaviw492139a2018-07-16 16:07:35 -07001874 frame.set(win.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001875 } else if (win.isLetterboxedAppWindow()) {
1876 frame.set(getTask().getBounds());
Winson Chungc1674272018-02-21 10:15:17 -08001877 } else if (win.isDockedResizing()) {
1878 // If we are animating while docked resizing, then use the stack bounds as the
1879 // animation target (which will be different than the task bounds)
1880 frame.set(getTask().getParent().getBounds());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001881 } else {
chaviw553b0212018-07-12 13:37:01 -07001882 frame.set(win.getContainingFrame());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001883 }
1884 surfaceInsets = win.getAttrs().surfaceInsets;
Adrian Roos20e07892018-02-23 19:12:01 +01001885 // XXX(b/72757033): These are insets relative to the window frame, but we're really
1886 // interested in the insets relative to the frame we chose in the if-blocks above.
chaviw9c81e632018-07-31 11:17:52 -07001887 win.getContentInsets(insets);
1888 win.getStableInsets(stableInsets);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001889 }
1890
1891 if (mLaunchTaskBehind) {
1892 // Differentiate the two animations. This one which is briefly on the screen
1893 // gets the !enter animation, and the other activity which remains on the
1894 // screen gets the enter animation. Both appear in the mOpeningApps set.
1895 enter = false;
1896 }
1897 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
1898 + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
1899 + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
1900 final Configuration displayConfig = displayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08001901 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001902 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
1903 surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
1904 if (a != null) {
1905 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
1906 final int containingWidth = frame.width();
1907 final int containingHeight = frame.height();
1908 a.initialize(containingWidth, containingHeight, width, height);
1909 a.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1910 }
1911 return a;
1912 }
1913
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001914 @Override
Jorim Jaggi6de61012018-03-19 14:53:23 +01001915 public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
1916 return mAnimatingAppWindowTokenRegistry != null
1917 && mAnimatingAppWindowTokenRegistry.notifyAboutToFinish(
1918 this, endDeferFinishCallback);
1919 }
1920
1921 @Override
1922 public void onAnimationLeashDestroyed(Transaction t) {
1923 super.onAnimationLeashDestroyed(t);
Vishnu Naira2977262018-07-26 13:31:26 -07001924 if (mAnimationBoundsLayer != null) {
1925 t.destroy(mAnimationBoundsLayer);
1926 mAnimationBoundsLayer = null;
1927 }
1928
Jorim Jaggi6de61012018-03-19 14:53:23 +01001929 if (mAnimatingAppWindowTokenRegistry != null) {
1930 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
1931 }
1932 }
1933
1934 @Override
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001935 protected void setLayer(Transaction t, int layer) {
1936 if (!mSurfaceAnimator.hasLeash()) {
1937 t.setLayer(mSurfaceControl, layer);
1938 }
1939 }
1940
1941 @Override
1942 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
1943 if (!mSurfaceAnimator.hasLeash()) {
1944 t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
1945 }
1946 }
1947
1948 @Override
1949 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
1950 if (!mSurfaceAnimator.hasLeash()) {
1951 t.reparent(mSurfaceControl, newParent.getHandle());
1952 }
1953 }
1954
1955 @Override
1956 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001957 // The leash is parented to the animation layer. We need to preserve the z-order by using
1958 // the prefix order index, but we boost if necessary.
Robert Carrb9506032018-02-13 13:54:00 -08001959 int layer = 0;
1960 if (!inPinnedWindowingMode()) {
1961 layer = getPrefixOrderIndex();
1962 } else {
1963 // Pinned stacks have animations take place within themselves rather than an animation
1964 // layer so we need to preserve the order relative to the stack (e.g. the order of our
1965 // task/parent).
1966 layer = getParent().getPrefixOrderIndex();
1967 }
1968
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001969 if (mNeedsZBoost) {
1970 layer += Z_BOOST_BASE;
1971 }
1972 leash.setLayer(layer);
Robert Carr2f8aa392018-01-31 14:46:51 -08001973
1974 final DisplayContent dc = getDisplayContent();
Jorim Jaggibe418292018-03-26 16:14:12 +02001975 dc.assignStackOrdering();
Jorim Jaggi6de61012018-03-19 14:53:23 +01001976 if (mAnimatingAppWindowTokenRegistry != null) {
1977 mAnimatingAppWindowTokenRegistry.notifyStarting(this);
1978 }
Vishnu Naira2977262018-07-26 13:31:26 -07001979
1980 // If the animation needs to be cropped then an animation bounds layer is created as a child
1981 // of the pinned stack or animation layer. The leash is then reparented to this new layer.
1982 if (mNeedsAnimationBoundsLayer) {
1983 final TaskStack stack = getStack();
1984 if (stack == null) {
1985 return;
1986 }
1987 mAnimationBoundsLayer = createAnimationBoundsLayer(t);
1988
1989 // Set clip rect to stack bounds.
1990 mTmpRect.setEmpty();
1991 stack.getBounds(mTmpRect);
1992
1993 // Crop to stack bounds.
1994 t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
1995
1996 // Reparent leash to animation bounds layer.
1997 t.reparent(leash, mAnimationBoundsLayer.getHandle());
1998 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +01001999 }
2000
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002001 /**
2002 * This must be called while inside a transaction.
2003 */
2004 void showAllWindowsLocked() {
2005 forAllWindows(windowState -> {
2006 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + windowState);
2007 windowState.performShowLocked();
2008 }, false /* traverseTopToBottom */);
Jorim Jaggia5e10572017-11-15 14:36:26 +01002009 }
2010
2011 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002012 protected void onAnimationFinished() {
2013 super.onAnimationFinished();
2014
2015 mTransit = TRANSIT_UNSET;
2016 mTransitFlags = 0;
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002017 mNeedsZBoost = false;
Vishnu Naira2977262018-07-26 13:31:26 -07002018 mNeedsAnimationBoundsLayer = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002019
2020 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
2021 "AppWindowToken");
2022
Jorim Jaggi988f6682017-11-17 17:46:43 +01002023 clearThumbnail();
Jorim Jaggi752cd822018-03-29 16:29:18 +02002024 setClientHidden(isHidden() && hiddenRequested);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002025
lumarkff0ab692018-11-05 20:32:30 +08002026 getDisplayContent().computeImeTargetIfNeeded(this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002027
2028 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this
2029 + ": reportedVisible=" + reportedVisible
2030 + " okToDisplay=" + okToDisplay()
2031 + " okToAnimate=" + okToAnimate()
2032 + " startingDisplayed=" + startingDisplayed);
2033
2034 // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
2035 // traverse the copy.
2036 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
2037 children.forEach(WindowState::onExitAnimationDone);
2038
lumark588a3e82018-07-20 18:53:54 +08002039 getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002040 scheduleAnimation();
2041 }
2042
2043 @Override
2044 boolean isAppAnimating() {
2045 return isSelfAnimating();
2046 }
2047
2048 @Override
2049 boolean isSelfAnimating() {
2050 // If we are about to start a transition, we also need to be considered animating.
2051 return isWaitingForTransitionStart() || isReallyAnimating();
2052 }
2053
2054 /**
2055 * @return True if and only if we are actually running an animation. Note that
2056 * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
2057 * start.
2058 */
2059 private boolean isReallyAnimating() {
2060 return super.isSelfAnimating();
2061 }
2062
Jorim Jaggi988f6682017-11-17 17:46:43 +01002063 @Override
2064 void cancelAnimation() {
2065 super.cancelAnimation();
2066 clearThumbnail();
2067 }
2068
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002069 boolean isWaitingForTransitionStart() {
lumark588a3e82018-07-20 18:53:54 +08002070 return getDisplayContent().mAppTransition.isTransitionSet()
2071 && (getDisplayContent().mOpeningApps.contains(this)
2072 || getDisplayContent().mClosingApps.contains(this));
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002073 }
2074
2075 public int getTransit() {
2076 return mTransit;
2077 }
2078
2079 int getTransitFlags() {
2080 return mTransitFlags;
2081 }
2082
Jorim Jaggi988f6682017-11-17 17:46:43 +01002083 void attachThumbnailAnimation() {
2084 if (!isReallyAnimating()) {
2085 return;
2086 }
2087 final int taskId = getTask().mTaskId;
2088 final GraphicBuffer thumbnailHeader =
lumark588a3e82018-07-20 18:53:54 +08002089 getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002090 if (thumbnailHeader == null) {
2091 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
2092 return;
2093 }
2094 clearThumbnail();
2095 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
2096 mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
2097 }
2098
Tony Mak64b8d562017-12-28 17:44:02 +00002099 /**
2100 * Attaches a surface with a thumbnail for the
2101 * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
2102 */
2103 void attachCrossProfileAppsThumbnailAnimation() {
2104 if (!isReallyAnimating()) {
2105 return;
2106 }
2107 clearThumbnail();
2108
2109 final WindowState win = findMainWindow();
2110 if (win == null) {
2111 return;
2112 }
chaviw492139a2018-07-16 16:07:35 -07002113 final Rect frame = win.getFrameLw();
Tony Mak64b8d562017-12-28 17:44:02 +00002114 final int thumbnailDrawableRes = getTask().mUserId == mService.mCurrentUserId
2115 ? R.drawable.ic_account_circle
Tony Makda4af232018-04-27 11:01:10 +01002116 : R.drawable.ic_corp_badge;
Tony Mak64b8d562017-12-28 17:44:02 +00002117 final GraphicBuffer thumbnail =
lumark588a3e82018-07-20 18:53:54 +08002118 getDisplayContent().mAppTransition
Tony Mak64b8d562017-12-28 17:44:02 +00002119 .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
2120 if (thumbnail == null) {
2121 return;
2122 }
2123 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
2124 final Animation animation =
lumark588a3e82018-07-20 18:53:54 +08002125 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
chaviw492139a2018-07-16 16:07:35 -07002126 win.getFrameLw());
Tony Mak64b8d562017-12-28 17:44:02 +00002127 mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
2128 frame.top));
2129 }
2130
Jorim Jaggi988f6682017-11-17 17:46:43 +01002131 private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
2132 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
2133
2134 // If this is a multi-window scenario, we use the windows frame as
2135 // destination of the thumbnail header animation. If this is a full screen
2136 // window scenario, we use the whole display as the target.
2137 WindowState win = findMainWindow();
2138 Rect appRect = win != null ? win.getContentFrameLw() :
2139 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
chaviw9c81e632018-07-31 11:17:52 -07002140 final Rect insets = win != null ? win.getContentInsets() : null;
Jorim Jaggi988f6682017-11-17 17:46:43 +01002141 final Configuration displayConfig = mDisplayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002142 return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
Jorim Jaggi988f6682017-11-17 17:46:43 +01002143 appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
2144 displayConfig.orientation);
2145 }
2146
2147 private void clearThumbnail() {
2148 if (mThumbnail == null) {
2149 return;
2150 }
2151 mThumbnail.destroy();
2152 mThumbnail = null;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002153 }
2154
Jorim Jaggif84e2f62018-01-16 14:17:59 +01002155 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
2156 mRemoteAnimationDefinition = definition;
2157 }
2158
2159 RemoteAnimationDefinition getRemoteAnimationDefinition() {
2160 return mRemoteAnimationDefinition;
2161 }
2162
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002163 @Override
2164 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2165 super.dump(pw, prefix, dumpAll);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002166 if (appToken != null) {
Wale Ogunwale72919d22016-12-08 18:58:50 -08002167 pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002168 }
Winson Chung48b25652018-10-22 14:04:30 -07002169 pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08002170 pw.print(prefix); pw.print("task="); pw.println(getTask());
Wale Ogunwale51362492016-09-08 17:49:17 -07002171 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
2172 pw.print(" mOrientation="); pw.println(mOrientation);
Wale Ogunwale89973222017-04-23 18:39:45 -07002173 pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
2174 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
2175 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07002176 if (paused) {
2177 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002178 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08002179 if (mAppStopped) {
2180 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
2181 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002182 if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002183 || allDrawn || mLastAllDrawn) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002184 pw.print(prefix); pw.print("mNumInterestingWindows=");
2185 pw.print(mNumInterestingWindows);
2186 pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002187 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07002188 pw.print(" allDrawn="); pw.print(allDrawn);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002189 pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
Craig Mautner6fbda632012-07-03 09:26:39 -07002190 pw.println(")");
2191 }
2192 if (inPendingTransaction) {
2193 pw.print(prefix); pw.print("inPendingTransaction=");
2194 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002195 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08002196 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002197 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
2198 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08002199 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08002200 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002201 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002202 if (startingWindow != null || startingSurface != null
Wale Ogunwale6c459212017-05-17 08:56:03 -07002203 || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002204 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002205 pw.print(" startingSurface="); pw.print(startingSurface);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002206 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale6c459212017-05-17 08:56:03 -07002207 pw.print(" startingMoved="); pw.print(startingMoved);
2208 pw.println(" mHiddenSetFromTransferredStartingWindow="
2209 + mHiddenSetFromTransferredStartingWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002210 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01002211 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08002212 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002213 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08002214 }
2215 if (mPendingRelaunchCount != 0) {
2216 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01002217 }
Wale Ogunwale9c64cb62017-04-12 13:39:59 -07002218 if (getController() != null) {
2219 pw.print(prefix); pw.print("controller="); pw.println(getController());
2220 }
Wale Ogunwalee287e192017-04-21 09:30:12 -07002221 if (mRemovingFromDisplay) {
2222 pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
2223 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002224 }
2225
2226 @Override
2227 void setHidden(boolean hidden) {
2228 super.setHidden(hidden);
Winson Chunge55c0192017-08-24 14:50:48 -07002229
2230 if (hidden) {
2231 // Once the app window is hidden, reset the last saved PiP snap fraction
2232 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
2233 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002234 scheduleAnimation();
2235 }
2236
2237 @Override
2238 void prepareSurfaces() {
2239 // isSelfAnimating also returns true when we are about to start a transition, so we need
2240 // to check super here.
2241 final boolean reallyAnimating = super.isSelfAnimating();
2242 final boolean show = !isHidden() || reallyAnimating;
2243 if (show && !mLastSurfaceShowing) {
2244 mPendingTransaction.show(mSurfaceControl);
2245 } else if (!show && mLastSurfaceShowing) {
2246 mPendingTransaction.hide(mSurfaceControl);
Jorim Jaggi4d1835d2017-08-31 17:28:27 +02002247 }
Jorim Jaggi988f6682017-11-17 17:46:43 +01002248 if (mThumbnail != null) {
2249 mThumbnail.setShowing(mPendingTransaction, show);
2250 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002251 mLastSurfaceShowing = show;
2252 super.prepareSurfaces();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002253 }
2254
Jorim Jaggi77d0f36c2018-03-16 17:49:49 +01002255 /**
2256 * @return Whether our {@link #getSurfaceControl} is currently showing.
2257 */
2258 boolean isSurfaceShowing() {
2259 return mLastSurfaceShowing;
2260 }
2261
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002262 boolean isFreezingScreen() {
2263 return mFreezingScreen;
2264 }
2265
2266 @Override
2267 boolean needsZBoost() {
2268 return mNeedsZBoost || super.needsZBoost();
2269 }
2270
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07002271 @CallSuper
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002272 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02002273 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07002274 final long token = proto.start(fieldId);
2275 writeNameToProto(proto, NAME);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002276 super.writeToProto(proto, WINDOW_TOKEN, trim);
Vishnu Nair04ab4392018-01-10 11:00:06 -08002277 proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
2278 proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
2279 proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
2280 if (mThumbnail != null){
2281 mThumbnail.writeToProto(proto, THUMBNAIL);
2282 }
2283 proto.write(FILLS_PARENT, mFillsParent);
2284 proto.write(APP_STOPPED, mAppStopped);
2285 proto.write(HIDDEN_REQUESTED, hiddenRequested);
2286 proto.write(CLIENT_HIDDEN, mClientHidden);
2287 proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
2288 proto.write(REPORTED_DRAWN, reportedDrawn);
2289 proto.write(REPORTED_VISIBLE, reportedVisible);
2290 proto.write(NUM_INTERESTING_WINDOWS, mNumInterestingWindows);
2291 proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
2292 proto.write(ALL_DRAWN, allDrawn);
2293 proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
2294 proto.write(REMOVED, removed);
2295 if (startingWindow != null){
2296 startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
2297 }
2298 proto.write(STARTING_DISPLAYED, startingDisplayed);
2299 proto.write(STARTING_MOVED, startingMoved);
2300 proto.write(HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW,
2301 mHiddenSetFromTransferredStartingWindow);
2302 for (Rect bounds : mFrozenBounds) {
2303 bounds.writeToProto(proto, FROZEN_BOUNDS);
2304 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002305 proto.end(token);
2306 }
2307
2308 void writeNameToProto(ProtoOutputStream proto, long fieldId) {
2309 if (appToken == null) {
2310 return;
2311 }
2312 try {
2313 proto.write(fieldId, appToken.getName());
2314 } catch (RemoteException e) {
2315 // This shouldn't happen, but in this case fall back to outputting nothing
2316 Slog.e(TAG, e.toString());
2317 }
2318 }
2319
2320 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002321 public String toString() {
2322 if (stringName == null) {
2323 StringBuilder sb = new StringBuilder();
2324 sb.append("AppWindowToken{");
2325 sb.append(Integer.toHexString(System.identityHashCode(this)));
2326 sb.append(" token="); sb.append(token); sb.append('}');
2327 stringName = sb.toString();
2328 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002329 return stringName + ((mIsExiting) ? " mIsExiting=" : "");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002330 }
Adrian Roos20e07892018-02-23 19:12:01 +01002331
2332 Rect getLetterboxInsets() {
2333 if (mLetterbox != null) {
2334 return mLetterbox.getInsets();
2335 } else {
2336 return new Rect();
2337 }
2338 }
Adrian Roos23df3a32018-03-15 15:41:13 +01002339
2340 /**
2341 * @eturn true if there is a letterbox and any part of that letterbox overlaps with
2342 * the given {@code rect}.
2343 */
2344 boolean isLetterboxOverlappingWith(Rect rect) {
2345 return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
2346 }
chaviw4ad54912018-05-30 11:05:44 -07002347
2348 /**
2349 * Sets if this AWT is in the process of closing or entering PIP.
2350 * {@link #mWillCloseOrEnterPip}}
2351 */
2352 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
2353 mWillCloseOrEnterPip = willCloseOrEnterPip;
2354 }
2355
2356 /**
2357 * Returns whether this AWT is considered closing. Conditions are either
2358 * 1. Is this app animating and was requested to be hidden
2359 * 2. App is delayed closing since it might enter PIP.
2360 */
2361 boolean isClosingOrEnteringPip() {
2362 return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
2363 }
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +02002364
2365 /**
2366 * @return Whether we are allowed to show non-starting windows at the moment. We disallow
2367 * showing windows during transitions in case we have windows that have wide-color-gamut
2368 * color mode set to avoid jank in the middle of the transition.
2369 */
2370 boolean canShowWindows() {
2371 return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
2372 }
2373
2374 /**
2375 * @return true if we have a window that has a non-default color mode set; false otherwise.
2376 */
2377 private boolean hasNonDefaultColorWindow() {
2378 return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
2379 true /* topToBottom */);
2380 }
lumark588a3e82018-07-20 18:53:54 +08002381
2382 void removeFromPendingTransition() {
2383 if (isWaitingForTransitionStart() && mDisplayContent != null) {
2384 mDisplayContent.mOpeningApps.remove(this);
2385 mDisplayContent.mClosingApps.remove(this);
2386 }
2387 }
Jeff Browne9bdb312012-04-05 15:30:10 -07002388}