blob: e0d3fbed45879224d0143f3b2a194fbc6fb40b0b [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;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080031import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020032import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070033import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080034import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070035import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080036import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
chaviw9c81e632018-07-31 11:17:52 -070037import static android.view.WindowManager.TRANSIT_UNSET;
Jorim Jaggic6976f02018-04-18 16:31:07 +020038import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
chaviw9c81e632018-07-31 11:17:52 -070039
Adrian Roose99bc052017-11-20 17:55:31 +010040import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
41import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070042import static com.android.server.wm.AppWindowTokenProto.ALL_DRAWN;
43import static com.android.server.wm.AppWindowTokenProto.APP_STOPPED;
44import static com.android.server.wm.AppWindowTokenProto.CLIENT_HIDDEN;
45import static com.android.server.wm.AppWindowTokenProto.DEFER_HIDING_CLIENT;
46import static com.android.server.wm.AppWindowTokenProto.FILLS_PARENT;
47import static com.android.server.wm.AppWindowTokenProto.FROZEN_BOUNDS;
48import static com.android.server.wm.AppWindowTokenProto.HIDDEN_REQUESTED;
49import static com.android.server.wm.AppWindowTokenProto.HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW;
50import static com.android.server.wm.AppWindowTokenProto.IS_REALLY_ANIMATING;
51import static com.android.server.wm.AppWindowTokenProto.IS_WAITING_FOR_TRANSITION_START;
52import static com.android.server.wm.AppWindowTokenProto.LAST_ALL_DRAWN;
53import static com.android.server.wm.AppWindowTokenProto.LAST_SURFACE_SHOWING;
54import static com.android.server.wm.AppWindowTokenProto.NAME;
55import static com.android.server.wm.AppWindowTokenProto.NUM_DRAWN_WINDOWS;
56import static com.android.server.wm.AppWindowTokenProto.NUM_INTERESTING_WINDOWS;
57import static com.android.server.wm.AppWindowTokenProto.REMOVED;
58import static com.android.server.wm.AppWindowTokenProto.REPORTED_DRAWN;
59import static com.android.server.wm.AppWindowTokenProto.REPORTED_VISIBLE;
60import static com.android.server.wm.AppWindowTokenProto.STARTING_DISPLAYED;
61import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED;
62import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
63import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
64import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
chaviw9c81e632018-07-31 11:17:52 -070065import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
67import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
68import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
69import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
70import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
71import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
72import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
73import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
74import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
75import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
76import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
77import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
78import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
79import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
80import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
81import static com.android.server.wm.WindowManagerService.logWithStack;
Vishnu Naira2977262018-07-26 13:31:26 -070082import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080083
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070084import android.annotation.CallSuper;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020085import android.app.Activity;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080086import android.app.ActivityManager;
Winson Chung48b25652018-10-22 14:04:30 -070087import android.content.ComponentName;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080088import android.content.res.CompatibilityInfo;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070089import android.content.res.Configuration;
Jorim Jaggi988f6682017-11-17 17:46:43 +010090import android.graphics.GraphicBuffer;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020091import android.graphics.Point;
Jorim Jaggi0429f352015-12-22 16:29:16 +010092import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070093import android.os.Binder;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -080094import android.os.Debug;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070095import android.os.IBinder;
Steven Timotiusaf03df62017-07-18 16:56:43 -070096import android.os.RemoteException;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080097import android.os.SystemClock;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020098import android.os.Trace;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080099import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700100import android.util.proto.ProtoOutputStream;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200101import android.view.DisplayInfo;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800102import android.view.IApplicationToken;
Robert Carr788f5742018-07-30 17:46:45 -0700103import android.view.InputApplicationHandle;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100104import android.view.RemoteAnimationDefinition;
Robert Carr6914f082017-03-20 19:04:30 -0700105import android.view.SurfaceControl;
Tony Mak64b8d562017-12-28 17:44:02 +0000106import android.view.SurfaceControl.Transaction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800107import android.view.WindowManager;
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200108import android.view.WindowManager.LayoutParams;
Tony Mak64b8d562017-12-28 17:44:02 +0000109import android.view.animation.Animation;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800110
Tony Mak64b8d562017-12-28 17:44:02 +0000111import com.android.internal.R;
Riddle Hsua118b3a2018-10-11 22:05:06 +0800112import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800113import com.android.internal.util.ToBooleanFunction;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800114import com.android.server.AttributeCache;
115import com.android.server.policy.WindowManagerPolicy;
Adrian Roose99bc052017-11-20 17:55:31 +0100116import com.android.server.policy.WindowManagerPolicy.StartingSurface;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800117import com.android.server.wm.WindowManagerService.H;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800118
119import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +0100120import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800121import java.util.ArrayList;
lumark588a3e82018-07-20 18:53:54 +0800122import java.util.function.Consumer;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800123
124class AppTokenList extends ArrayList<AppWindowToken> {
125}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800126
127/**
128 * Version of WindowToken that is specifically for a particular application (or
129 * really activity) that is displaying windows.
130 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800131class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener,
132 ConfigurationContainerListener {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800133 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
134
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100135 /**
136 * Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
137 */
138 private static final int Z_BOOST_BASE = 800570000;
139
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800140 // Non-null only for application tokens.
141 final IApplicationToken appToken;
Winson Chung48b25652018-10-22 14:04:30 -0700142 final ComponentName mActivityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800143 final boolean mVoiceInteraction;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700144
Wale Ogunwale51362492016-09-08 17:49:17 -0700145 /** @see WindowContainer#fillsParent() */
146 private boolean mFillsParent;
Craig Mautner4c5eb222013-11-18 12:59:05 -0800147 boolean layoutConfigChanges;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800148 boolean mShowForAllUsers;
149 int mTargetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -0700150
Bryce Lee6d410262017-02-28 15:30:17 -0800151 // Flag set while reparenting to prevent actions normally triggered by an individual parent
152 // change.
153 private boolean mReparenting;
154
Wale Ogunwalee287e192017-04-21 09:30:12 -0700155 // True if we are current in the process of removing this app token from the display
156 private boolean mRemovingFromDisplay = false;
157
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800158 // The input dispatching timeout for this application token in nanoseconds.
Wale Ogunwale72919d22016-12-08 18:58:50 -0800159 long mInputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800160
161 // These are used for determining when all windows associated with
162 // an activity have been drawn, so they can be made visible together
163 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -0700164 // initialize so that it doesn't match mTransactionSequence which is an int.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700165 private long mLastTransactionSequence = Long.MIN_VALUE;
166 private int mNumInterestingWindows;
167 private int mNumDrawnWindows;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800168 boolean inPendingTransaction;
169 boolean allDrawn;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000170 private boolean mLastAllDrawn;
171
Craig Mautner7636dfb2012-11-16 15:24:11 -0800172 // Set to true when this app creates a surface while in the middle of an animation. In that
173 // case do not clear allDrawn until the animation completes.
174 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800175
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800176 // Is this window's surface needed? This is almost like hidden, except
177 // it will sometimes be true a little earlier: when the token has
178 // been shown, but is still waiting for its app transition to execute
179 // before making its windows shown.
180 boolean hiddenRequested;
181
182 // Have we told the window clients to hide themselves?
Wale Ogunwale89973222017-04-23 18:39:45 -0700183 private boolean mClientHidden;
184
185 // If true we will defer setting mClientHidden to true and reporting to the client that it is
186 // hidden.
187 boolean mDeferHidingClient;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800188
189 // Last visibility state we reported to the app token.
190 boolean reportedVisible;
191
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700192 // Last drawn state we reported to the app token.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700193 private boolean reportedDrawn;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700194
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800195 // Set to true when the token has been removed from the window mgr.
196 boolean removed;
197
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800198 // Information about an application starting window if displayed.
199 StartingData startingData;
200 WindowState startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800201 StartingSurface startingSurface;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800202 boolean startingDisplayed;
203 boolean startingMoved;
Jorim Jaggi60f9c972018-02-01 19:21:07 +0100204
Wale Ogunwale6c459212017-05-17 08:56:03 -0700205 // True if the hidden state of this token was forced to false due to a transferred starting
206 // window.
207 private boolean mHiddenSetFromTransferredStartingWindow;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800208 boolean firstWindowDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700209 private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
210 new WindowState.UpdateReportedVisibilityResults();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800211
212 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700213 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800214
Wale Ogunwale571771c2016-08-26 13:18:50 -0700215 // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
Craig Mautner799bc1d2015-01-14 10:33:48 -0800216 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800217
Craig Mautnerbb742462014-07-07 15:28:55 -0700218 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700219 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700220
Wale Ogunwale72919d22016-12-08 18:58:50 -0800221 private boolean mAlwaysFocusable;
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800222
Robert Carre12aece2016-02-02 22:43:27 -0800223 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700224 int mRotationAnimationHint;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700225 private int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800226
Jorim Jaggife762342016-10-13 14:33:27 +0200227 private boolean mLastContainsShowWhenLockedWindow;
228 private boolean mLastContainsDismissKeyguardWindow;
229
Jorim Jaggi0429f352015-12-22 16:29:16 +0100230 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700231 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100232
Wale Ogunwale6c459212017-05-17 08:56:03 -0700233 private boolean mDisablePreviewScreenshots;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +0100234
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700235 private Task mLastParent;
Robert Carred3e83b2017-04-21 13:26:55 -0700236
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800237 // TODO: Remove after unification
238 ActivityRecord mActivityRecord;
239
chaviwd3bf08d2017-08-01 17:24:59 -0700240 /**
241 * See {@link #canTurnScreenOn()}
242 */
243 private boolean mCanTurnScreenOn = true;
244
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200245 /**
246 * If we are running an animation, this determines the transition type. Must be one of
247 * AppTransition.TRANSIT_* constants.
248 */
249 private int mTransit;
250
251 /**
252 * If we are running an animation, this determines the flags during this animation. Must be a
253 * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
254 */
255 private int mTransitFlags;
256
257 /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
Jorim Jaggifd1891462017-12-29 15:41:36 +0100258 private boolean mLastSurfaceShowing = true;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200259
Jorim Jaggi988f6682017-11-17 17:46:43 +0100260 private AppWindowThumbnail mThumbnail;
261
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000262 /** Have we been asked to have this token keep the screen frozen? */
263 private boolean mFreezingScreen;
264
265 /** Whether this token should be boosted at the top of all app window tokens. */
266 private boolean mNeedsZBoost;
Adrian Roos4d18a2e2017-12-19 19:08:05 +0100267 private Letterbox mLetterbox;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000268
chaviw23ee71c2017-12-18 11:29:41 -0800269 private final Point mTmpPoint = new Point();
chaviw23012112017-12-20 15:29:04 -0800270 private final Rect mTmpRect = new Rect();
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100271 private RemoteAnimationDefinition mRemoteAnimationDefinition;
Jorim Jaggi6de61012018-03-19 14:53:23 +0100272 private AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry;
chaviw23ee71c2017-12-18 11:29:41 -0800273
chaviw4ad54912018-05-30 11:05:44 -0700274 /**
275 * A flag to determine if this AWT is in the process of closing or entering PIP. This is needed
276 * to help AWT know that the app is in the process of closing but hasn't yet started closing on
277 * the WM side.
278 */
279 private boolean mWillCloseOrEnterPip;
280
Vishnu Naira2977262018-07-26 13:31:26 -0700281 /** Layer used to constrain the animation to a token's stack bounds. */
282 SurfaceControl mAnimationBoundsLayer;
283
284 /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
285 boolean mNeedsAnimationBoundsLayer;
286
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800287 private static final int STARTING_WINDOW_TYPE_NONE = 0;
288 private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
289 private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
290
Winson Chung48b25652018-10-22 14:04:30 -0700291 AppWindowToken(WindowManagerService service, IApplicationToken token,
292 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
293 long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
294 int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
295 boolean launchTaskBehind, boolean alwaysFocusable,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800296 ActivityRecord activityRecord) {
Winson Chung48b25652018-10-22 14:04:30 -0700297 this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800298 // TODO: remove after unification
299 mActivityRecord = activityRecord;
300 mActivityRecord.registerConfigurationChangeListener(this);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800301 mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800302 mShowForAllUsers = showForAllUsers;
303 mTargetSdk = targetSdk;
304 mOrientation = orientation;
305 layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0;
306 mLaunchTaskBehind = launchTaskBehind;
307 mAlwaysFocusable = alwaysFocusable;
308 mRotationAnimationHint = rotationAnimationHint;
309
310 // Application tokens start out hidden.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200311 setHidden(true);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800312 hiddenRequested = true;
313 }
314
Winson Chung48b25652018-10-22 14:04:30 -0700315 AppWindowToken(WindowManagerService service, IApplicationToken token,
316 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
317 boolean fillsParent) {
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800318 super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
319 false /* ownerCanManageAppTokens */);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700320 appToken = token;
Winson Chung48b25652018-10-22 14:04:30 -0700321 mActivityComponent = activityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800322 mVoiceInteraction = voiceInteraction;
Wale Ogunwale17f175c2017-02-07 16:54:10 -0800323 mFillsParent = fillsParent;
Robert Carr0bcbe642018-10-11 19:07:43 -0700324 mInputApplicationHandle = new InputApplicationHandle(appToken.asBinder());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800325 }
326
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800327 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
328 firstWindowDrawn = true;
329
330 // We now have a good window to show, remove dead placeholders
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700331 removeDeadWindows();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800332
Jorim Jaggi02886a82016-12-06 09:10:06 -0800333 if (startingWindow != null) {
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800334 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
335 + win.mToken + ": first real window is shown, no animation");
336 // If this initial window is animating, stop it -- we will do an animation to reveal
337 // it from behind the starting window, so there is no need for it to also be doing its
338 // own stuff.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100339 win.cancelAnimation();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800340 removeStartingWindow();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800341 }
342 updateReportedVisibilityLocked();
343 }
344
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800345 void updateReportedVisibilityLocked() {
346 if (appToken == null) {
347 return;
348 }
349
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700350 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700351 final int count = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800352
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700353 mReportedVisibilityResults.reset();
354
355 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700356 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700357 win.updateReportedVisibility(mReportedVisibilityResults);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800358 }
359
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700360 int numInteresting = mReportedVisibilityResults.numInteresting;
361 int numVisible = mReportedVisibilityResults.numVisible;
362 int numDrawn = mReportedVisibilityResults.numDrawn;
363 boolean nowGone = mReportedVisibilityResults.nowGone;
364
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700365 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200366 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !isHidden();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700367 if (!nowGone) {
368 // If the app is not yet gone, then it can only become visible/drawn.
369 if (!nowDrawn) {
370 nowDrawn = reportedDrawn;
371 }
372 if (!nowVisible) {
373 nowVisible = reportedVisible;
374 }
375 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800376 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800377 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700378 if (nowDrawn != reportedDrawn) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800379 if (mActivityRecord != null) {
380 mActivityRecord.onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700381 }
382 reportedDrawn = nowDrawn;
383 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800384 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700385 if (DEBUG_VISIBILITY) Slog.v(TAG,
386 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800387 reportedVisible = nowVisible;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800388 if (mActivityRecord != null) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800389 if (nowVisible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800390 onWindowsVisible();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800391 } else {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800392 onWindowsGone();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800393 }
394 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800395 }
396 }
397
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800398 private void onWindowsGone() {
399 if (mActivityRecord == null) {
400 return;
401 }
402 if (DEBUG_VISIBILITY) {
403 Slog.v(TAG_WM, "Reporting gone in " + mActivityRecord.appToken);
404 }
405 mActivityRecord.onWindowsGone();
406 }
407
408 private void onWindowsVisible() {
409 if (mActivityRecord == null) {
410 return;
411 }
412 if (DEBUG_VISIBILITY) {
413 Slog.v(TAG_WM, "Reporting visible in " + mActivityRecord.appToken);
414 }
415 mActivityRecord.onWindowsVisible();
416 }
417
Wale Ogunwale89973222017-04-23 18:39:45 -0700418 boolean isClientHidden() {
419 return mClientHidden;
420 }
421
422 void setClientHidden(boolean hideClient) {
423 if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
424 return;
425 }
Jorim Jaggi067b5bf2018-02-23 17:42:39 +0100426 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
427 + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
Wale Ogunwale89973222017-04-23 18:39:45 -0700428 mClientHidden = hideClient;
429 sendAppVisibilityToClients();
430 }
431
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800432 void setVisibility(boolean visible, boolean deferHidingClient) {
433 final AppTransition appTransition = getDisplayContent().mAppTransition;
434
435 // Don't set visibility to false if we were already not visible. This prevents WM from
436 // adding the app to the closing app list which doesn't make sense for something that is
437 // already not visible. However, set visibility to true even if we are already visible.
438 // This makes sure the app is added to the opening apps list so that the right
439 // transition can be selected.
440 // TODO: Probably a good idea to separate the concept of opening/closing apps from the
441 // concept of setting visibility...
442 if (!visible && hiddenRequested) {
443
444 if (!deferHidingClient && mDeferHidingClient) {
445 // We previously deferred telling the client to hide itself when visibility was
446 // initially set to false. Now we would like it to hide, so go ahead and set it.
447 mDeferHidingClient = deferHidingClient;
448 setClientHidden(true);
449 }
450 return;
451 }
452
453 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
454 Slog.v(TAG_WM, "setAppVisibility("
455 + appToken + ", visible=" + visible + "): " + appTransition
456 + " hidden=" + isHidden() + " hiddenRequested="
457 + hiddenRequested + " Callers=" + Debug.getCallers(6));
458 }
459
460 final DisplayContent displayContent = getDisplayContent();
461 displayContent.mOpeningApps.remove(this);
462 displayContent.mClosingApps.remove(this);
463 waitingToShow = false;
464 hiddenRequested = !visible;
465 mDeferHidingClient = deferHidingClient;
466
467 if (!visible) {
468 // If the app is dead while it was visible, we kept its dead window on screen.
469 // Now that the app is going invisible, we can remove it. It will be restarted
470 // if made visible again.
471 removeDeadWindows();
472 } else {
473 if (!appTransition.isTransitionSet()
474 && appTransition.isReady()) {
475 // Add the app mOpeningApps if transition is unset but ready. This means
476 // we're doing a screen freeze, and the unfreeze will wait for all opening
477 // apps to be ready.
478 displayContent.mOpeningApps.add(this);
479 }
480 startingMoved = false;
481 // If the token is currently hidden (should be the common case), or has been
482 // stopped, then we need to set up to wait for its windows to be ready.
483 if (isHidden() || mAppStopped) {
484 clearAllDrawn();
485
486 // If the app was already visible, don't reset the waitingToShow state.
487 if (isHidden()) {
488 waitingToShow = true;
489 }
490 }
491
492 // In the case where we are making an app visible but holding off for a transition,
493 // we still need to tell the client to make its windows visible so they get drawn.
494 // Otherwise, we will wait on performing the transition until all windows have been
495 // drawn, they never will be, and we are sad.
496 setClientHidden(false);
497
498 requestUpdateWallpaperIfNeeded();
499
500 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + this);
501 mAppStopped = false;
502
503 transferStartingWindowFromHiddenAboveTokenIfNeeded();
504 }
505
506 // If we are preparing an app transition, then delay changing
507 // the visibility of this token until we execute that transition.
508 if (okToAnimate() && appTransition.isTransitionSet()) {
509 inPendingTransaction = true;
510 if (visible) {
511 displayContent.mOpeningApps.add(this);
512 mEnteringAnimation = true;
513 } else {
514 displayContent.mClosingApps.add(this);
515 mEnteringAnimation = false;
516 }
517 if (appTransition.getAppTransition()
518 == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
519 // We're launchingBehind, add the launching activity to mOpeningApps.
520 final WindowState win = getDisplayContent().findFocusedWindow();
521 if (win != null) {
522 final AppWindowToken focusedToken = win.mAppToken;
523 if (focusedToken != null) {
524 if (DEBUG_APP_TRANSITIONS) {
525 Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
526 + " adding " + focusedToken + " to mOpeningApps");
527 }
528 // Force animation to be loaded.
529 focusedToken.setHidden(true);
530 displayContent.mOpeningApps.add(focusedToken);
531 }
532 }
533 }
534 return;
535 }
536
537 commitVisibility(null, visible, TRANSIT_UNSET, true, mVoiceInteraction);
538 updateReportedVisibilityLocked();
539 }
540
541 boolean commitVisibility(WindowManager.LayoutParams lp,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700542 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
543
544 boolean delayed = false;
545 inPendingTransaction = false;
Wale Ogunwale9e4721f2017-05-23 19:37:30 -0700546 // Reset the state of mHiddenSetFromTransferredStartingWindow since visibility is actually
547 // been set by the app now.
548 mHiddenSetFromTransferredStartingWindow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700549
550 // Allow for state changes and animation to be applied if:
551 // * token is transitioning visibility state
552 // * or the token was marked as hidden and is exiting before we had a chance to play the
553 // transition animation
554 // * or this is an opening app and windows are being replaced.
555 boolean visibilityChanged = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200556 if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800557 final AccessibilityController accessibilityController =
558 mWmService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700559 boolean changed = false;
560 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200561 "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700562
563 boolean runningAppAnimation = false;
564
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100565 if (transit != WindowManager.TRANSIT_UNSET) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200566 if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700567 delayed = runningAppAnimation = true;
568 }
569 final WindowState window = findMainWindow();
570 //TODO (multidisplay): Magnification is supported only for the default display.
571 if (window != null && accessibilityController != null
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700572 && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700573 accessibilityController.onAppWindowTransitionLocked(window, transit);
574 }
575 changed = true;
576 }
577
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700578 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700579 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700580 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700581 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700582 }
583
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200584 setHidden(!visible);
585 hiddenRequested = !visible;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700586 visibilityChanged = true;
587 if (!visible) {
588 stopFreezingScreen(true, true);
589 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700590 // If we are being set visible, and the starting window is not yet displayed,
591 // then make sure it doesn't get displayed.
592 if (startingWindow != null && !startingWindow.isDrawnLw()) {
593 startingWindow.mPolicyVisibility = false;
594 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700595 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -0700596
597 // We are becoming visible, so better freeze the screen with the windows that are
598 // getting visible so we also wait for them.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800599 forAllWindows(mWmService::makeWindowFreezingScreenIfNeededLocked, true);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700600 }
601
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800602 if (DEBUG_APP_TRANSITIONS) {
603 Slog.v(TAG_WM, "commitVisibility: " + this
604 + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
605 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700606
607 if (changed) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800608 getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700609 if (performLayout) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800610 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700611 false /*updateInputWindows*/);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800612 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700613 }
Arthur Hung95b38a92018-07-20 18:56:12 +0800614 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700615 }
616 }
617
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200618 if (isReallyAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700619 delayed = true;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100620 } else {
621
622 // We aren't animating anything, but exiting windows rely on the animation finished
623 // callback being called in case the AppWindowToken was pretending to be animating,
624 // which we might have done because we were in closing/opening apps list.
625 onAnimationFinished();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700626 }
627
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700628 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100629 if ((mChildren.get(i)).isSelfOrChildAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700630 delayed = true;
631 }
632 }
633
634 if (visibilityChanged) {
635 if (visible && !delayed) {
636 // The token was made immediately visible, there will be no entrance animation.
637 // We need to inform the client the enter animation was finished.
638 mEnteringAnimation = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800639 mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(
640 token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700641 }
Robert Carr61b81112017-07-17 18:08:15 -0700642
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800643 // If we're becoming visible, immediately change client visibility as well. there seem
644 // to be some edge cases where we change our visibility but client visibility never gets
645 // updated.
Jorim Jaggi110839b2018-01-22 12:49:04 +0100646 // If we're becoming invisible, update the client visibility if we are not running an
647 // animation. Otherwise, we'll update client visibility in onAnimationFinished.
Jorim Jaggi3cad57f2018-02-20 18:32:01 +0100648 if (visible || !isReallyAnimating()) {
Jorim Jaggi110839b2018-01-22 12:49:04 +0100649 setClientHidden(!visible);
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100650 }
651
lumark588a3e82018-07-20 18:53:54 +0800652 if (!getDisplayContent().mClosingApps.contains(this)
653 && !getDisplayContent().mOpeningApps.contains(this)) {
chaviwa953fcf2018-03-01 12:00:39 -0800654 // The token is not closing nor opening, so even if there is an animation set, that
655 // doesn't mean that it goes through the normal app transition cycle so we have
656 // to inform the docked controller about visibility change.
657 // TODO(multi-display): notify docked divider on all displays where visibility was
658 // affected.
lumark588a3e82018-07-20 18:53:54 +0800659 getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged();
chaviwa953fcf2018-03-01 12:00:39 -0800660
661 // Take the screenshot before possibly hiding the WSA, otherwise the screenshot
662 // will not be taken.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800663 mWmService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
chaviwa953fcf2018-03-01 12:00:39 -0800664 }
665
Robert Carre7cc44d2017-03-20 19:04:30 -0700666 // If we are hidden but there is no delay needed we immediately
667 // apply the Surface transaction so that the ActivityManager
Robert Carr61b81112017-07-17 18:08:15 -0700668 // can have some guarantee on the Surface state following
669 // setting the visibility. This captures cases like dismissing
670 // the docked or pinned stack where there is no app transition.
671 //
672 // In the case of a "Null" animation, there will be
673 // no animation but there will still be a transition set.
674 // We still need to delay hiding the surface such that it
675 // can be synchronized with showing the next surface in the transition.
lumark588a3e82018-07-20 18:53:54 +0800676 if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) {
Robert Carr6914f082017-03-20 19:04:30 -0700677 SurfaceControl.openTransaction();
678 for (int i = mChildren.size() - 1; i >= 0; i--) {
679 mChildren.get(i).mWinAnimator.hide("immediately hidden");
680 }
681 SurfaceControl.closeTransaction();
682 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700683 }
684
685 return delayed;
686 }
687
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200688 /**
689 * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns
690 * true.
691 */
692 WindowState getTopFullscreenWindow() {
693 for (int i = mChildren.size() - 1; i >= 0; i--) {
694 final WindowState win = mChildren.get(i);
695 if (win != null && win.mAttrs.isFullscreen()) {
696 return win;
697 }
698 }
699 return null;
700 }
701
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800702 WindowState findMainWindow() {
Matthew Ng53e66b22018-01-12 17:13:13 -0800703 return findMainWindow(true);
704 }
705
706 /**
707 * Finds the main window that either has type base application or application starting if
708 * requested.
709 *
710 * @param includeStartingApp Allow to search application-starting windows to also be returned.
711 * @return The main window of type base application or application starting if requested.
712 */
713 WindowState findMainWindow(boolean includeStartingApp) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700714 WindowState candidate = null;
Matthew Ng53e66b22018-01-12 17:13:13 -0800715 for (int j = mChildren.size() - 1; j >= 0; --j) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700716 final WindowState win = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700717 final int type = win.mAttrs.type;
718 // No need to loop through child window as base application and starting types can't be
719 // child windows.
Matthew Ng53e66b22018-01-12 17:13:13 -0800720 if (type == TYPE_BASE_APPLICATION
721 || (includeStartingApp && type == TYPE_APPLICATION_STARTING)) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700722 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900723 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700724 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800725 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700726 candidate = win;
727 } else {
728 return win;
729 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800730 }
731 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700732 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800733 }
734
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800735 boolean windowsAreFocusable() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700736 return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800737 }
738
Wale Ogunwale571771c2016-08-26 13:18:50 -0700739 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700740 boolean isVisible() {
Wale Ogunwalee471be62016-10-03 07:53:55 -0700741 // If the app token isn't hidden then it is considered visible and there is no need to check
742 // its children windows to see if they are visible.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200743 return !isHidden();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700744 }
745
746 @Override
Wale Ogunwalee287e192017-04-21 09:30:12 -0700747 void removeImmediately() {
748 onRemovedFromDisplay();
749 super.removeImmediately();
750 }
751
752 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700753 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800754 mIsExiting = false;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800755 removeAllWindowsIfPossible();
Bryce Lee6d410262017-02-28 15:30:17 -0800756 removeImmediately();
Craig Mautnere3119b72015-01-20 15:02:36 -0800757 }
758
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700759 @Override
760 boolean checkCompleteDeferredRemoval() {
761 if (mIsExiting) {
762 removeIfPossible();
763 }
764 return super.checkCompleteDeferredRemoval();
765 }
766
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700767 void onRemovedFromDisplay() {
Wale Ogunwalee287e192017-04-21 09:30:12 -0700768 if (mRemovingFromDisplay) {
769 return;
770 }
771 mRemovingFromDisplay = true;
772
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700773 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
774
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800775 boolean delayed = commitVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700776
lumark588a3e82018-07-20 18:53:54 +0800777 getDisplayContent().mOpeningApps.remove(this);
778 getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800779 mWmService.mTaskSnapshotController.onAppRemoved(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700780 waitingToShow = false;
lumark588a3e82018-07-20 18:53:54 +0800781 if (getDisplayContent().mClosingApps.contains(this)) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700782 delayed = true;
lumark588a3e82018-07-20 18:53:54 +0800783 } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
784 getDisplayContent().mClosingApps.add(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700785 delayed = true;
786 }
787
788 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200789 + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700790
791 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
792 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
793
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800794 if (startingData != null) {
795 removeStartingWindow();
Jorim Jaggi19be6052017-08-03 18:33:43 +0200796 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800797
Winson Chung87e5d552017-04-05 11:49:38 -0700798 // If this window was animating, then we need to ensure that the app transition notifies
lumark588a3e82018-07-20 18:53:54 +0800799 // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
800 // so add to that list now
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200801 if (isSelfAnimating()) {
lumark588a3e82018-07-20 18:53:54 +0800802 getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
Winson Chung87e5d552017-04-05 11:49:38 -0700803 }
804
Wale Ogunwalee287e192017-04-21 09:30:12 -0700805 final TaskStack stack = getStack();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700806 if (delayed && !isEmpty()) {
807 // set the token aside because it has an active animation to be finished
808 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
809 "removeAppToken make exiting: " + this);
Wale Ogunwalee287e192017-04-21 09:30:12 -0700810 if (stack != null) {
811 stack.mExitingAppTokens.add(this);
812 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700813 mIsExiting = true;
814 } else {
815 // Make sure there is no animation running on this token, so any windows associated
816 // with it will be removed as soon as their animations are complete
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200817 cancelAnimation();
Wale Ogunwale3106ae012017-05-16 08:56:37 -0700818 if (stack != null) {
819 stack.mExitingAppTokens.remove(this);
820 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700821 removeIfPossible();
822 }
823
824 removed = true;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700825 stopFreezingScreen(true, true);
Bryce Lee6d410262017-02-28 15:30:17 -0800826
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800827 final DisplayContent dc = getDisplayContent();
828 if (dc.mFocusedApp == this) {
829 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
830 + " displayId=" + dc.getDisplayId());
831 dc.setFocusedApp(null);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800832 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700833 }
834
835 if (!delayed) {
836 updateReportedVisibilityLocked();
837 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700838
839 mRemovingFromDisplay = false;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700840 }
841
Chong Zhange05bcb12016-07-26 17:47:29 -0700842 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700843 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700844 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700845 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700846 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700847 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700848 if (wallpaperMightChange) {
849 requestUpdateWallpaperIfNeeded();
850 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700851 }
852
Robert Carre12aece2016-02-02 22:43:27 -0800853 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700854 destroySurfaces(false /*cleanupOnResume*/);
855 }
856
857 /**
858 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
859 * the client has finished with them.
860 *
861 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
862 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
863 * others so that they are ready to be reused. If set to false (common case), destroy all
864 * surfaces that's eligible, if the app is already stopped.
865 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700866 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700867 boolean destroyedSomething = false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100868
869 // Copying to a different list as multiple children can be removed.
Jorim Jaggi59f3e922018-01-05 15:40:32 +0100870 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100871 for (int i = children.size() - 1; i >= 0; i--) {
872 final WindowState win = children.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700873 destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
Robert Carre12aece2016-02-02 22:43:27 -0800874 }
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700875 if (destroyedSomething) {
876 final DisplayContent dc = getDisplayContent();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700877 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Adrian Roos23df3a32018-03-15 15:41:13 +0100878 updateLetterboxSurface(null);
Robert Carre12aece2016-02-02 22:43:27 -0800879 }
880 }
881
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800882 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700883 * Notify that the app is now resumed, and it was not stopped before, perform a clean
884 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800885 */
Jorim Jaggibae01b12017-04-11 16:29:10 -0700886 void notifyAppResumed(boolean wasStopped) {
Chong Zhangad24f962016-08-25 12:12:33 -0700887 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
Jorim Jaggibae01b12017-04-11 16:29:10 -0700888 + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700889 mAppStopped = false;
chaviwd3bf08d2017-08-01 17:24:59 -0700890 // Allow the window to turn the screen on once the app is resumed again.
891 setCanTurnScreenOn(true);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700892 if (!wasStopped) {
893 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800894 }
Robert Carre12aece2016-02-02 22:43:27 -0800895 }
896
Chong Zhangbef461f2015-10-27 11:38:24 -0700897 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700898 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
899 * keeping alive in case they were still being used.
900 */
901 void notifyAppStopped() {
902 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
903 mAppStopped = true;
904 destroySurfaces();
905 // Remove any starting window that was added for this app if they are still around.
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800906 removeStartingWindow();
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700907 }
908
Chong Zhang92147042016-05-09 12:47:11 -0700909 void clearAllDrawn() {
910 allDrawn = false;
911 deferClearAllDrawn = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700912 }
913
Bryce Lee6d410262017-02-28 15:30:17 -0800914 Task getTask() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800915 return (Task) getParent();
Bryce Lee6d410262017-02-28 15:30:17 -0800916 }
917
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800918 TaskStack getStack() {
919 final Task task = getTask();
920 if (task != null) {
921 return task.mStack;
922 } else {
923 return null;
924 }
925 }
926
Bryce Lee6d410262017-02-28 15:30:17 -0800927 @Override
928 void onParentSet() {
929 super.onParentSet();
930
Robert Carred3e83b2017-04-21 13:26:55 -0700931 final Task task = getTask();
932
Bryce Lee6d410262017-02-28 15:30:17 -0800933 // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
934 // access visual elements like the {@link DisplayContent}. We must remove any associations
935 // such as animations.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800936 if (!mReparenting) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800937 if (task == null) {
938 // It is possible we have been marked as a closing app earlier. We must remove ourselves
939 // from this list so we do not participate in any future animations.
lumark588a3e82018-07-20 18:53:54 +0800940 getDisplayContent().mClosingApps.remove(this);
Robert Carred3e83b2017-04-21 13:26:55 -0700941 } else if (mLastParent != null && mLastParent.mStack != null) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800942 task.mStack.mExitingAppTokens.remove(this);
943 }
Bryce Lee6d410262017-02-28 15:30:17 -0800944 }
Jorim Jaggi6de61012018-03-19 14:53:23 +0100945 final TaskStack stack = getStack();
946
947 // If we reparent, make sure to remove ourselves from the old animation registry.
948 if (mAnimatingAppWindowTokenRegistry != null) {
949 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
950 }
951 mAnimatingAppWindowTokenRegistry = stack != null
952 ? stack.getAnimatingAppWindowTokenRegistry()
953 : null;
954
Robert Carred3e83b2017-04-21 13:26:55 -0700955 mLastParent = task;
Bryce Lee6d410262017-02-28 15:30:17 -0800956 }
957
Wale Ogunwalefa854eb2016-09-20 13:43:52 -0700958 void postWindowRemoveStartingWindowCleanup(WindowState win) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700959 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700960 if (startingWindow == win) {
961 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800962 removeStartingWindow();
Wale Ogunwale6c459212017-05-17 08:56:03 -0700963 } else if (mChildren.size() == 0) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700964 // If this is the last window and we had requested a starting transition window,
965 // well there is no point now.
Jorim Jaggi02886a82016-12-06 09:10:06 -0800966 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700967 startingData = null;
Wale Ogunwale6c459212017-05-17 08:56:03 -0700968 if (mHiddenSetFromTransferredStartingWindow) {
969 // We set the hidden state to false for the token from a transferred starting window.
970 // We now reset it back to true since the starting window was the last window in the
971 // token.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200972 setHidden(true);
Wale Ogunwale6c459212017-05-17 08:56:03 -0700973 }
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100974 } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700975 // If this is the last window except for a starting transition window,
976 // we need to get rid of the starting transition.
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200977 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
978 + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800979 removeStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700980 }
981 }
982
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700983 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700984 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700985 WindowState win = mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800986 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700987 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700988 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800989 // Set mDestroying, we don't want any animation or delayed removal here.
990 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700991 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700992 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800993 }
994 }
995 }
996
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700997 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700998 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700999 // No need to loop through child windows as the answer should be the same as that of the
1000 // parent window.
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001001 if (!(mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001002 return true;
1003 }
1004 }
1005 return false;
1006 }
1007
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001008 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001009 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1010 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -08001011
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001012 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001013 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001014 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -08001015 }
Robert Carra1eb4392015-12-10 12:43:51 -08001016 }
1017
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001018 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001019 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -08001020 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001021 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001022 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001023 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -08001024 }
1025 }
1026
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001027 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001028 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1029 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -08001030
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001031 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001032 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001033 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -08001034 }
1035 }
1036
Chong Zhang4d7369a2016-04-25 16:09:14 -07001037 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001038 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001039 final WindowState w = mChildren.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -07001040 w.requestUpdateWallpaperIfNeeded();
1041 }
1042 }
1043
Chong Zhangd78ddb42016-03-02 17:01:14 -08001044 boolean isRelaunching() {
1045 return mPendingRelaunchCount > 0;
1046 }
1047
Robert Carr68375192017-06-13 12:41:53 -07001048 boolean shouldFreezeBounds() {
1049 final Task task = getTask();
1050
1051 // For freeform windows, we can't freeze the bounds at the moment because this would make
1052 // the resizing unresponsive.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001053 if (task == null || task.inFreeformWindowingMode()) {
Robert Carr68375192017-06-13 12:41:53 -07001054 return false;
1055 }
1056
1057 // We freeze the bounds while drag resizing to deal with the time between
1058 // the divider/drag handle being released, and the handling it's new
1059 // configuration. If we are relaunched outside of the drag resizing state,
1060 // we need to be careful not to do this.
1061 return getTask().isDragResizing();
1062 }
1063
Chong Zhangd78ddb42016-03-02 17:01:14 -08001064 void startRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001065 if (shouldFreezeBounds()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001066 freezeBounds();
1067 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001068
1069 // In the process of tearing down before relaunching, the app will
1070 // try and clean up it's child surfaces. We need to prevent this from
1071 // happening, so we sever the children, transfering their ownership
1072 // from the client it-self to the parent surface (owned by us).
Robert Carr29daa922018-04-27 11:56:48 -07001073 detachChildren();
1074
1075 mPendingRelaunchCount++;
1076 }
1077
1078 void detachChildren() {
Robert Carrfd8e93b2018-05-10 13:40:25 -07001079 SurfaceControl.openTransaction();
Robert Carrd5c7dd62017-03-08 10:39:30 -08001080 for (int i = mChildren.size() - 1; i >= 0; i--) {
1081 final WindowState w = mChildren.get(i);
1082 w.mWinAnimator.detachChildren();
1083 }
Robert Carrfd8e93b2018-05-10 13:40:25 -07001084 SurfaceControl.closeTransaction();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001085 }
1086
1087 void finishRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001088 unfreezeBounds();
1089
Chong Zhangd78ddb42016-03-02 17:01:14 -08001090 if (mPendingRelaunchCount > 0) {
1091 mPendingRelaunchCount--;
Bryce Lee081554b2017-05-25 07:52:12 -07001092 } else {
1093 // Update keyguard flags upon finishing relaunch.
1094 checkKeyguardFlagsChanged();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001095 }
1096 }
1097
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001098 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001099 if (mPendingRelaunchCount == 0) {
1100 return;
1101 }
Robert Carr68375192017-06-13 12:41:53 -07001102 unfreezeBounds();
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001103 mPendingRelaunchCount = 0;
1104 }
1105
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001106 /**
1107 * Returns true if the new child window we are adding to this token is considered greater than
1108 * the existing child window in this token in terms of z-order.
1109 */
1110 @Override
1111 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
1112 WindowState existingWindow) {
1113 final int type1 = newWindow.mAttrs.type;
1114 final int type2 = existingWindow.mAttrs.type;
1115
1116 // Base application windows should be z-ordered BELOW all other windows in the app token.
1117 if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
1118 return false;
1119 } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
1120 return true;
1121 }
1122
1123 // Starting windows should be z-ordered ABOVE all other windows in the app token.
1124 if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
1125 return true;
1126 } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
1127 return false;
1128 }
1129
1130 // Otherwise the new window is greater than the existing window.
1131 return true;
1132 }
1133
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001134 @Override
Robert Carra1eb4392015-12-10 12:43:51 -08001135 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001136 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001137
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001138 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001139 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001140 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001141 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
1142 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001143
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001144 // if we got a replacement window, reset the timeout to give drawing more time
1145 if (gotReplacementWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001146 mWmService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -08001147 }
Jorim Jaggife762342016-10-13 14:33:27 +02001148 checkKeyguardFlagsChanged();
1149 }
1150
1151 @Override
1152 void removeChild(WindowState child) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001153 if (!mChildren.contains(child)) {
1154 // This can be true when testing.
1155 return;
1156 }
Jorim Jaggife762342016-10-13 14:33:27 +02001157 super.removeChild(child);
1158 checkKeyguardFlagsChanged();
Adrian Roos23df3a32018-03-15 15:41:13 +01001159 updateLetterboxSurface(child);
Robert Carra1eb4392015-12-10 12:43:51 -08001160 }
1161
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001162 private boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001163 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001164 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001165 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -08001166 return true;
1167 }
1168 }
1169 return false;
1170 }
1171
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001172 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001173 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001174 (mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -08001175 }
1176 }
1177
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001178 void reparent(Task task, int position) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001179 if (DEBUG_ADD_REMOVE) {
1180 Slog.i(TAG_WM, "reparent: moving app token=" + this
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001181 + " to task=" + task.mTaskId + " at " + position);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001182 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001183 if (task == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001184 throw new IllegalArgumentException("reparent: could not find task");
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001185 }
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001186 final Task currentTask = getTask();
1187 if (task == currentTask) {
Winson Chung30480042017-01-26 10:55:34 -08001188 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001189 "window token=" + this + " already child of task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001190 }
Bryce Lee6d410262017-02-28 15:30:17 -08001191
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001192 if (currentTask.mStack != task.mStack) {
Bryce Lee6d410262017-02-28 15:30:17 -08001193 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001194 "window token=" + this + " current task=" + currentTask
Bryce Lee6d410262017-02-28 15:30:17 -08001195 + " belongs to a different stack than " + task);
1196 }
1197
Winson Chung30480042017-01-26 10:55:34 -08001198 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001199 + " from task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001200 final DisplayContent prevDisplayContent = getDisplayContent();
1201
Bryce Lee6d410262017-02-28 15:30:17 -08001202 mReparenting = true;
1203
Winson Chung30480042017-01-26 10:55:34 -08001204 getParent().removeChild(this);
1205 task.addChild(this, position);
1206
Bryce Lee6d410262017-02-28 15:30:17 -08001207 mReparenting = false;
1208
Winson Chung30480042017-01-26 10:55:34 -08001209 // Relayout display(s).
1210 final DisplayContent displayContent = task.getDisplayContent();
1211 displayContent.setLayoutNeeded();
1212 if (prevDisplayContent != displayContent) {
1213 onDisplayChanged(displayContent);
1214 prevDisplayContent.setLayoutNeeded();
1215 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001216 getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
Winson Chung30480042017-01-26 10:55:34 -08001217 }
1218
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001219 @Override
1220 void onDisplayChanged(DisplayContent dc) {
1221 DisplayContent prevDc = mDisplayContent;
1222 super.onDisplayChanged(dc);
1223 if (prevDc != null && prevDc.mFocusedApp == this) {
1224 prevDc.setFocusedApp(null);
lumarkbf844642018-11-23 17:11:36 +08001225 final TaskStack stack = dc.getTopStack();
1226 if (stack != null) {
1227 final Task task = stack.getTopChild();
1228 if (task != null && task.getTopChild() == this) {
1229 dc.setFocusedApp(this);
1230 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001231 }
1232 }
1233 }
1234
Jorim Jaggi0429f352015-12-22 16:29:16 +01001235 /**
1236 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
1237 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
1238 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
1239 * with a queue.
1240 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001241 private void freezeBounds() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001242 final Task task = getTask();
1243 mFrozenBounds.offer(new Rect(task.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001244
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001245 if (task.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001246 // We didn't call prepareFreezingBounds on the task, so use the current value.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001247 mFrozenMergedConfig.offer(new Configuration(task.getConfiguration()));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001248 } else {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001249 mFrozenMergedConfig.offer(new Configuration(task.mPreparedFrozenMergedConfig));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001250 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001251 // Calling unset() to make it equal to Configuration.EMPTY.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001252 task.mPreparedFrozenMergedConfig.unset();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001253 }
1254
1255 /**
1256 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
1257 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001258 private void unfreezeBounds() {
Robert Carr68375192017-06-13 12:41:53 -07001259 if (mFrozenBounds.isEmpty()) {
1260 return;
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001261 }
Robert Carr68375192017-06-13 12:41:53 -07001262 mFrozenBounds.remove();
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001263 if (!mFrozenMergedConfig.isEmpty()) {
1264 mFrozenMergedConfig.remove();
1265 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001266 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001267 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001268 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +01001269 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001270 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001271 }
1272
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001273 void setAppLayoutChanges(int changes, String reason) {
1274 if (!mChildren.isEmpty()) {
1275 final DisplayContent dc = getDisplayContent();
1276 dc.pendingLayoutChanges |= changes;
1277 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001278 mWmService.mWindowPlacerLocked.debugLayoutRepeats(reason, dc.pendingLayoutChanges);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001279 }
1280 }
1281 }
1282
1283 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001284 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001285 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001286 if (win.removeReplacedWindowIfNeeded(replacement)) {
1287 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001288 }
1289 }
1290 }
1291
1292 void startFreezingScreen() {
1293 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001294 + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001295 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001296 if (!hiddenRequested) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001297 if (!mFreezingScreen) {
1298 mFreezingScreen = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001299 mWmService.registerAppFreezeListener(this);
1300 mWmService.mAppsFreezingScreen++;
1301 if (mWmService.mAppsFreezingScreen == 1) {
1302 mWmService.startFreezingDisplayLocked(0, 0, getDisplayContent());
1303 mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1304 mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001305 }
1306 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001307 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001308 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001309 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001310 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001311 }
1312 }
1313 }
1314
1315 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001316 if (!mFreezingScreen) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001317 return;
1318 }
1319 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001320 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001321 boolean unfrozeWindows = false;
1322 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001323 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001324 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001325 }
1326 if (force || unfrozeWindows) {
1327 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001328 mFreezingScreen = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001329 mWmService.unregisterAppFreezeListener(this);
1330 mWmService.mAppsFreezingScreen--;
1331 mWmService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001332 }
1333 if (unfreezeSurfaceNow) {
1334 if (unfrozeWindows) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001335 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001336 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001337 mWmService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001338 }
1339 }
1340
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001341 @Override
1342 public void onAppFreezeTimeout() {
1343 Slog.w(TAG_WM, "Force clearing freeze: " + this);
1344 stopFreezingScreen(true, true);
1345 }
1346
Jorim Jaggi60f9c972018-02-01 19:21:07 +01001347 /**
1348 * Tries to transfer the starting window from a token that's above ourselves in the task but
1349 * not visible anymore. This is a common scenario apps use: Trampoline activity T start main
1350 * activity M in the same task. Now, when reopening the task, T starts on top of M but then
1351 * immediately finishes after, so we have to transfer T to M.
1352 */
1353 void transferStartingWindowFromHiddenAboveTokenIfNeeded() {
1354 final Task task = getTask();
1355 for (int i = task.mChildren.size() - 1; i >= 0; i--) {
1356 final AppWindowToken fromToken = task.mChildren.get(i);
1357 if (fromToken == this) {
1358 return;
1359 }
1360 if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) {
1361 return;
1362 }
1363 }
1364 }
1365
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001366 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001367 final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001368 if (fromToken == null) {
1369 return false;
1370 }
1371
1372 final WindowState tStartingWindow = fromToken.startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001373 if (tStartingWindow != null && fromToken.startingSurface != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001374 // In this case, the starting icon has already been displayed, so start
1375 // letting windows get shown immediately without any more transitions.
lumark588a3e82018-07-20 18:53:54 +08001376 getDisplayContent().mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001377
1378 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1379 + " from " + fromToken + " to " + this);
1380
1381 final long origId = Binder.clearCallingIdentity();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001382 try {
1383 // Transfer the starting window over to the new token.
1384 startingData = fromToken.startingData;
1385 startingSurface = fromToken.startingSurface;
1386 startingDisplayed = fromToken.startingDisplayed;
1387 fromToken.startingDisplayed = false;
1388 startingWindow = tStartingWindow;
1389 reportedVisible = fromToken.reportedVisible;
1390 fromToken.startingData = null;
1391 fromToken.startingSurface = null;
1392 fromToken.startingWindow = null;
1393 fromToken.startingMoved = true;
1394 tStartingWindow.mToken = this;
1395 tStartingWindow.mAppToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001396
Peter Visontay3556a3b2017-11-01 17:23:17 +00001397 if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1398 "Removing starting " + tStartingWindow + " from " + fromToken);
1399 fromToken.removeChild(tStartingWindow);
1400 fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
1401 fromToken.mHiddenSetFromTransferredStartingWindow = false;
1402 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001403
Peter Visontay3556a3b2017-11-01 17:23:17 +00001404 // Propagate other interesting state between the tokens. If the old token is displayed,
1405 // we should immediately force the new one to be displayed. If it is animating, we need
1406 // to move that animation to the new one.
1407 if (fromToken.allDrawn) {
1408 allDrawn = true;
1409 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1410 }
1411 if (fromToken.firstWindowDrawn) {
1412 firstWindowDrawn = true;
1413 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001414 if (!fromToken.isHidden()) {
1415 setHidden(false);
Peter Visontay3556a3b2017-11-01 17:23:17 +00001416 hiddenRequested = false;
1417 mHiddenSetFromTransferredStartingWindow = true;
1418 }
1419 setClientHidden(fromToken.mClientHidden);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001420
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001421 transferAnimation(fromToken);
1422
1423 // When transferring an animation, we no longer need to apply an animation to the
1424 // the token we transfer the animation over. Thus, remove the animation from
1425 // pending opening apps.
lumark588a3e82018-07-20 18:53:54 +08001426 getDisplayContent().mOpeningApps.remove(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001427
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001428 mWmService.updateFocusedWindowLocked(
Peter Visontay3556a3b2017-11-01 17:23:17 +00001429 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
1430 getDisplayContent().setLayoutNeeded();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001431 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001432 } finally {
1433 Binder.restoreCallingIdentity(origId);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001434 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001435 return true;
1436 } else if (fromToken.startingData != null) {
1437 // The previous app was getting ready to show a
1438 // starting window, but hasn't yet done so. Steal it!
1439 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1440 "Moving pending starting from " + fromToken + " to " + this);
1441 startingData = fromToken.startingData;
1442 fromToken.startingData = null;
1443 fromToken.startingMoved = true;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001444 scheduleAddStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001445 return true;
1446 }
1447
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001448 // TODO: Transfer thumbnail
1449
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001450 return false;
1451 }
1452
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001453 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001454 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001455 }
1456
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001457 @Override
1458 void onAppTransitionDone() {
1459 sendingToBottom = false;
1460 }
1461
Wale Ogunwale51362492016-09-08 17:49:17 -07001462 /**
1463 * We override because this class doesn't want its children affecting its reported orientation
1464 * in anyway.
1465 */
1466 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001467 int getOrientation(int candidate) {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001468 if (candidate == SCREEN_ORIENTATION_BEHIND) {
1469 // Allow app to specify orientation regardless of its visibility state if the current
1470 // candidate want us to use orientation behind. I.e. the visible app on-top of this one
1471 // wants us to use the orientation of the app behind it.
1472 return mOrientation;
1473 }
1474
Bryce Lee61fbcbc2017-03-10 14:14:03 -08001475 // The {@link AppWindowToken} should only specify an orientation when it is not closing or
1476 // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
1477 // an Activity in another task being started in the wrong orientation during the transition.
lumark588a3e82018-07-20 18:53:54 +08001478 if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
1479 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
Bryce Leea163b762017-01-24 11:05:01 -08001480 return mOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07001481 }
Bryce Leea163b762017-01-24 11:05:01 -08001482
1483 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001484 }
1485
Wale Ogunwaleb198b742016-12-01 08:44:09 -08001486 /** Returns the app's preferred orientation regardless of its currently visibility state. */
1487 int getOrientationIgnoreVisibility() {
1488 return mOrientation;
1489 }
1490
Craig Mautnerdbb79912012-03-01 18:59:14 -08001491 @Override
Winson Chunge55c0192017-08-24 14:50:48 -07001492 public void onConfigurationChanged(Configuration newParentConfig) {
1493 final int prevWinMode = getWindowingMode();
1494 super.onConfigurationChanged(newParentConfig);
1495 final int winMode = getWindowingMode();
1496
1497 if (prevWinMode == winMode) {
1498 return;
1499 }
1500
1501 if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) {
1502 // Entering PiP from fullscreen, reset the snap fraction
1503 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
Winson Chung82267ce2018-04-06 16:38:26 -07001504 } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED
1505 && !isHidden()) {
Winson Chunge55c0192017-08-24 14:50:48 -07001506 // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
1507 // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
1508 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
1509 if (pinnedStack != null) {
Winson Chung8efa1652018-06-06 09:34:23 -07001510 final Rect stackBounds;
1511 if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
1512 // We are animating the bounds, use the pre-animation bounds to save the snap
1513 // fraction
1514 stackBounds = pinnedStack.mPreAnimationBounds;
1515 } else {
1516 // We skip the animation if the fullscreen configuration is not compatible, so
1517 // use the current bounds to calculate the saved snap fraction instead
1518 // (see PinnedActivityStack.skipResizeAnimation())
1519 stackBounds = mTmpRect;
1520 pinnedStack.getBounds(stackBounds);
1521 }
Winson Chunge55c0192017-08-24 14:50:48 -07001522 mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
Winson Chung8efa1652018-06-06 09:34:23 -07001523 stackBounds);
Winson Chunge55c0192017-08-24 14:50:48 -07001524 }
1525 }
1526 }
1527
1528 @Override
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001529 void checkAppWindowsReadyToShow() {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001530 if (allDrawn == mLastAllDrawn) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001531 return;
1532 }
1533
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001534 mLastAllDrawn = allDrawn;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001535 if (!allDrawn) {
1536 return;
1537 }
1538
1539 // The token has now changed state to having all windows shown... what to do, what to do?
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001540 if (mFreezingScreen) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001541 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001542 stopFreezingScreen(false, true);
1543 if (DEBUG_ORIENTATION) Slog.i(TAG,
1544 "Setting mOrientationChangeComplete=true because wtoken " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001545 + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001546 // This will set mOrientationChangeComplete and cause a pass through layout.
1547 setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001548 "checkAppWindowsReadyToShow: freezingScreen");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001549 } else {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001550 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001551
1552 // We can now show all of the drawn windows!
lumark588a3e82018-07-20 18:53:54 +08001553 if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001554 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001555 }
1556 }
1557 }
1558
Matthew Ng5d23afa2017-06-21 16:16:24 -07001559 /**
Bryce Leed390deb2017-06-22 13:14:28 -07001560 * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
1561 * child {@link WindowState}. A child is considered if it has been passed into
1562 * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
1563 * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
1564 * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
1565 *
1566 * @return {@code true} If all children have been considered, {@code false}.
1567 */
1568 private boolean allDrawnStatesConsidered() {
Bryce Lee6311c4b2017-07-06 14:09:29 -07001569 for (int i = mChildren.size() - 1; i >= 0; --i) {
1570 final WindowState child = mChildren.get(i);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001571 if (child.mightAffectAllDrawn() && !child.getDrawnStateEvaluated()) {
Bryce Leed390deb2017-06-22 13:14:28 -07001572 return false;
1573 }
1574 }
1575 return true;
1576 }
1577
1578 /**
Matthew Ng5d23afa2017-06-21 16:16:24 -07001579 * Determines if the token has finished drawing. This should only be called from
1580 * {@link DisplayContent#applySurfaceChangesTransaction}
1581 */
Matthew Ng498c71d2017-04-18 13:55:45 -07001582 void updateAllDrawn() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001583 if (!allDrawn) {
Matthew Ng498c71d2017-04-18 13:55:45 -07001584 // Number of drawn windows can be less when a window is being relaunched, wait for
Bryce Leed390deb2017-06-22 13:14:28 -07001585 // all windows to be launched and drawn for this token be considered all drawn.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001586 final int numInteresting = mNumInterestingWindows;
Bryce Leed390deb2017-06-22 13:14:28 -07001587
1588 // We must make sure that all present children have been considered (determined by
1589 // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
1590 // drawn.
1591 if (numInteresting > 0 && allDrawnStatesConsidered()
1592 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001593 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001594 + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001595 allDrawn = true;
1596 // Force an additional layout pass where
1597 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
Matthew Ng498c71d2017-04-18 13:55:45 -07001598 if (mDisplayContent != null) {
1599 mDisplayContent.setLayoutNeeded();
1600 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001601 mWmService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Robert Carrecc06b32017-04-18 14:25:10 -07001602
Winson Chunge7ba6862017-05-24 12:13:33 -07001603 // Notify the pinned stack upon all windows drawn. If there was an animation in
1604 // progress then this signal will resume that animation.
Wale Ogunwale61911492017-10-11 08:50:50 -07001605 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
Winson Chunge7ba6862017-05-24 12:13:33 -07001606 if (pinnedStack != null) {
1607 pinnedStack.onAllWindowsDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -07001608 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001609 }
1610 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001611 }
1612
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001613 boolean keyDispatchingTimedOut(String reason, int windowPid) {
1614 return mActivityRecord != null && mActivityRecord.keyDispatchingTimedOut(reason, windowPid);
1615 }
1616
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001617 /**
1618 * Updated this app token tracking states for interesting and drawn windows based on the window.
1619 *
1620 * @return Returns true if the input window is considered interesting and drawn while all the
1621 * windows in this app token where not considered drawn as of the last pass.
1622 */
1623 boolean updateDrawnWindowStates(WindowState w) {
Bryce Leed390deb2017-06-22 13:14:28 -07001624 w.setDrawnStateEvaluated(true /*evaluated*/);
1625
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001626 if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001627 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001628 + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001629 }
1630
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001631 if (allDrawn && !mFreezingScreen) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001632 return false;
1633 }
1634
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001635 if (mLastTransactionSequence != mWmService.mTransactionSequence) {
1636 mLastTransactionSequence = mWmService.mTransactionSequence;
Matthew Ng53e66b22018-01-12 17:13:13 -08001637 mNumDrawnWindows = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001638 startingDisplayed = false;
Matthew Ng53e66b22018-01-12 17:13:13 -08001639
1640 // There is the main base application window, even if it is exiting, wait for it
1641 mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001642 }
1643
1644 final WindowStateAnimator winAnimator = w.mWinAnimator;
1645
1646 boolean isInterestingAndDrawn = false;
1647
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001648 if (!allDrawn && w.mightAffectAllDrawn()) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001649 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1650 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001651 + ", isAnimationSet=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001652 if (!w.isDrawnLw()) {
1653 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
1654 + " pv=" + w.mPolicyVisibility
1655 + " mDrawState=" + winAnimator.drawStateToString()
1656 + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001657 + " a=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001658 }
1659 }
1660
1661 if (w != startingWindow) {
1662 if (w.isInteresting()) {
Matthew Ng53e66b22018-01-12 17:13:13 -08001663 // Add non-main window as interesting since the main app has already been added
1664 if (findMainWindow(false /* includeStartingApp */) != w) {
1665 mNumInterestingWindows++;
1666 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001667 if (w.isDrawnLw()) {
1668 mNumDrawnWindows++;
1669
1670 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
1671 + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001672 + " freezingScreen=" + mFreezingScreen
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001673 + " mAppFreezing=" + w.mAppFreezing);
1674
1675 isInterestingAndDrawn = true;
1676 }
1677 }
1678 } else if (w.isDrawnLw()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001679 if (mActivityRecord != null) {
1680 mActivityRecord.onStartingWindowDrawn(SystemClock.uptimeMillis());
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001681 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001682 startingDisplayed = true;
1683 }
1684 }
1685
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001686 return isInterestingAndDrawn;
1687 }
1688
Adrian Roos23df3a32018-03-15 15:41:13 +01001689 void layoutLetterbox(WindowState winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001690 final WindowState w = findMainWindow();
Adrian Roosf93b6d22018-03-21 13:48:26 +01001691 if (w == null || winHint != null && w != winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001692 return;
1693 }
Jorim Jaggia32da382018-03-28 18:01:22 +02001694 final boolean surfaceReady = w.isDrawnLw() // Regular case
Adrian Roosf93b6d22018-03-21 13:48:26 +01001695 || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
1696 || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
1697 final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001698 if (needsLetterbox) {
1699 if (mLetterbox == null) {
1700 mLetterbox = new Letterbox(() -> makeChildSurface(null));
1701 }
chaviw492139a2018-07-16 16:07:35 -07001702 mLetterbox.layout(getParent().getBounds(), w.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001703 } else if (mLetterbox != null) {
Adrian Roos23df3a32018-03-15 15:41:13 +01001704 mLetterbox.hide();
1705 }
1706 }
1707
1708 void updateLetterboxSurface(WindowState winHint) {
1709 final WindowState w = findMainWindow();
1710 if (w != winHint && winHint != null && w != null) {
1711 return;
1712 }
1713 layoutLetterbox(winHint);
1714 if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
1715 mLetterbox.applySurfaceChanges(mPendingTransaction);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001716 }
1717 }
1718
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001719 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001720 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001721 // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
1722 // before the non-exiting app tokens. So, we skip the exiting app tokens here.
1723 // TODO: Investigate if we need to continue to do this or if we can just process them
1724 // in-order.
1725 if (mIsExiting && !waitingForReplacement()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001726 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001727 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001728 return forAllWindowsUnchecked(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001729 }
1730
lumark588a3e82018-07-20 18:53:54 +08001731 @Override
1732 void forAllAppWindows(Consumer<AppWindowToken> callback) {
1733 callback.accept(this);
1734 }
1735
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001736 boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
1737 boolean traverseTopToBottom) {
1738 return super.forAllWindows(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001739 }
1740
1741 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001742 AppWindowToken asAppWindowToken() {
1743 // I am an app window token!
1744 return this;
1745 }
1746
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001747 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1748 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1749 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1750 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1751 // If the display is frozen, we won't do anything until the actual window is
1752 // displayed so there is no reason to put in the starting window.
1753 if (!okToDisplay()) {
1754 return false;
1755 }
1756
1757 if (startingData != null) {
1758 return false;
1759 }
1760
1761 final WindowState mainWin = findMainWindow();
1762 if (mainWin != null && mainWin.mWinAnimator.getShown()) {
1763 // App already has a visible window...why would you want a starting window?
1764 return false;
1765 }
1766
1767 final ActivityManager.TaskSnapshot snapshot =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001768 mWmService.mTaskSnapshotController.getSnapshot(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001769 getTask().mTaskId, getTask().mUserId,
1770 false /* restoreFromDisk */, false /* reducedResolution */);
1771 final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
1772 allowTaskSnapshot, activityCreated, fromRecents, snapshot);
1773
1774 if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
1775 return createSnapshot(snapshot);
1776 }
1777
1778 // If this is a translucent window, then don't show a starting window -- the current
1779 // effect (a full-screen opaque starting window that fades away to the real contents
1780 // when it is ready) does not work for this.
1781 if (DEBUG_STARTING_WINDOW) {
1782 Slog.v(TAG, "Checking theme of starting window: 0x" + Integer.toHexString(theme));
1783 }
1784 if (theme != 0) {
1785 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
1786 com.android.internal.R.styleable.Window,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001787 mWmService.mCurrentUserId);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001788 if (ent == null) {
1789 // Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
1790 // see that.
1791 return false;
1792 }
1793 final boolean windowIsTranslucent = ent.array.getBoolean(
1794 com.android.internal.R.styleable.Window_windowIsTranslucent, false);
1795 final boolean windowIsFloating = ent.array.getBoolean(
1796 com.android.internal.R.styleable.Window_windowIsFloating, false);
1797 final boolean windowShowWallpaper = ent.array.getBoolean(
1798 com.android.internal.R.styleable.Window_windowShowWallpaper, false);
1799 final boolean windowDisableStarting = ent.array.getBoolean(
1800 com.android.internal.R.styleable.Window_windowDisablePreview, false);
1801 if (DEBUG_STARTING_WINDOW) {
1802 Slog.v(TAG, "Translucent=" + windowIsTranslucent
1803 + " Floating=" + windowIsFloating
1804 + " ShowWallpaper=" + windowShowWallpaper);
1805 }
1806 if (windowIsTranslucent) {
1807 return false;
1808 }
1809 if (windowIsFloating || windowDisableStarting) {
1810 return false;
1811 }
1812 if (windowShowWallpaper) {
1813 if (getDisplayContent().mWallpaperController
1814 .getWallpaperTarget() == null) {
1815 // If this theme is requesting a wallpaper, and the wallpaper
1816 // is not currently visible, then this effectively serves as
1817 // an opaque window and our starting window transition animation
1818 // can still work. We just need to make sure the starting window
1819 // is also showing the wallpaper.
1820 windowFlags |= FLAG_SHOW_WALLPAPER;
1821 } else {
1822 return false;
1823 }
1824 }
1825
1826 if (transferStartingWindow(transferFrom)) {
1827 return true;
1828 }
1829
1830 // There is no existing starting window, and we don't want to create a splash screen, so
1831 // that's it!
1832 if (type != STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
1833 return false;
1834 }
1835
1836 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001837 startingData = new SplashScreenStartingData(mWmService, pkg,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001838 theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
1839 getMergedOverrideConfiguration());
1840 scheduleAddStartingWindow();
1841 }
1842 return true;
1843 }
1844
1845
1846 private boolean createSnapshot(ActivityManager.TaskSnapshot snapshot) {
1847 if (snapshot == null) {
1848 return false;
1849 }
1850
1851 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001852 startingData = new SnapshotStartingData(mWmService, snapshot);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001853 scheduleAddStartingWindow();
1854 return true;
1855 }
1856
1857 void scheduleAddStartingWindow() {
1858 // Note: we really want to do sendMessageAtFrontOfQueue() because we
1859 // want to process the message ASAP, before any other queued
1860 // messages.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001861 if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001862 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001863 mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001864 }
1865 }
1866
1867 private final Runnable mAddStartingWindow = new Runnable() {
1868
1869 @Override
1870 public void run() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001871 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001872 // There can only be one adding request, silly caller!
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001873 mWmService.mAnimationHandler.removeCallbacks(this);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001874 }
1875
1876 if (startingData == null) {
1877 // Animation has been canceled... do nothing.
1878 if (DEBUG_STARTING_WINDOW) {
1879 Slog.v(TAG, "startingData was nulled out before handling"
1880 + " mAddStartingWindow: " + AppWindowToken.this);
1881 }
1882 return;
1883 }
1884
1885 if (DEBUG_STARTING_WINDOW) {
1886 Slog.v(TAG, "Add starting " + this + ": startingData=" + startingData);
1887 }
1888
1889 WindowManagerPolicy.StartingSurface surface = null;
1890 try {
1891 surface = startingData.createStartingSurface(AppWindowToken.this);
1892 } catch (Exception e) {
1893 Slog.w(TAG, "Exception when adding starting window", e);
1894 }
1895 if (surface != null) {
1896 boolean abort = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001897 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001898 // If the window was successfully added, then
1899 // we need to remove it.
1900 if (removed || startingData == null) {
1901 if (DEBUG_STARTING_WINDOW) {
1902 Slog.v(TAG, "Aborted starting " + AppWindowToken.this
1903 + ": removed=" + removed + " startingData=" + startingData);
1904 }
1905 startingWindow = null;
1906 startingData = null;
1907 abort = true;
1908 } else {
1909 startingSurface = surface;
1910 }
1911 if (DEBUG_STARTING_WINDOW && !abort) {
1912 Slog.v(TAG, "Added starting " + AppWindowToken.this + ": startingWindow="
1913 + startingWindow + " startingView=" + startingSurface);
1914 }
1915 }
1916 if (abort) {
1917 surface.remove();
1918 }
1919 } else if (DEBUG_STARTING_WINDOW) {
1920 Slog.v(TAG, "Surface returned was null: " + AppWindowToken.this);
1921 }
1922 }
1923 };
1924
1925 private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
1926 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
1927 ActivityManager.TaskSnapshot snapshot) {
1928 if (getDisplayContent().mAppTransition.getAppTransition()
1929 == TRANSIT_DOCK_TASK_FROM_RECENTS) {
1930 // TODO(b/34099271): Remove this statement to add back the starting window and figure
1931 // out why it causes flickering, the starting window appears over the thumbnail while
1932 // the docked from recents transition occurs
1933 return STARTING_WINDOW_TYPE_NONE;
1934 } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
1935 return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1936 } else if (taskSwitch && allowTaskSnapshot) {
1937 return snapshot == null ? STARTING_WINDOW_TYPE_NONE
1938 : snapshotOrientationSameAsTask(snapshot) || fromRecents
1939 ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1940 } else {
1941 return STARTING_WINDOW_TYPE_NONE;
1942 }
1943 }
1944
1945
1946 private boolean snapshotOrientationSameAsTask(ActivityManager.TaskSnapshot snapshot) {
1947 if (snapshot == null) {
1948 return false;
1949 }
1950 return getTask().getConfiguration().orientation == snapshot.getOrientation();
1951 }
1952
1953 void removeStartingWindow() {
1954 if (startingWindow == null) {
1955 if (startingData != null) {
1956 // Starting window has not been added yet, but it is scheduled to be added.
1957 // Go ahead and cancel the request.
1958 if (DEBUG_STARTING_WINDOW) {
1959 Slog.v(TAG_WM, "Clearing startingData for token=" + this);
1960 }
1961 startingData = null;
1962 }
1963 return;
1964 }
1965
1966 final WindowManagerPolicy.StartingSurface surface;
1967 if (startingData != null) {
1968 surface = startingSurface;
1969 startingData = null;
1970 startingSurface = null;
1971 startingWindow = null;
1972 startingDisplayed = false;
1973 if (surface == null) {
1974 if (DEBUG_STARTING_WINDOW) {
1975 Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
1976 + "remove");
1977 }
1978 return;
1979 }
1980 } else {
1981 if (DEBUG_STARTING_WINDOW) {
1982 Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
1983 + this);
1984 }
1985 return;
1986 }
1987
1988 if (DEBUG_STARTING_WINDOW) {
1989 Slog.v(TAG_WM, "Schedule remove starting " + this
1990 + " startingWindow=" + startingWindow
1991 + " startingView=" + startingSurface
1992 + " Callers=" + Debug.getCallers(5));
1993 }
1994
1995 // Use the same thread to remove the window as we used to add it, as otherwise we end up
1996 // with things in the view hierarchy being called from different threads.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001997 mWmService.mAnimationHandler.post(() -> {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001998 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
1999 try {
2000 surface.remove();
2001 } catch (Exception e) {
2002 Slog.w(TAG_WM, "Exception when removing starting window", e);
2003 }
2004 });
2005 }
2006
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07002007 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07002008 boolean fillsParent() {
2009 return mFillsParent;
2010 }
2011
2012 void setFillsParent(boolean fillsParent) {
2013 mFillsParent = fillsParent;
2014 }
2015
Jorim Jaggife762342016-10-13 14:33:27 +02002016 boolean containsDismissKeyguardWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002017 // Window state is transient during relaunch. We are not guaranteed to be frozen during the
2018 // entirety of the relaunch.
2019 if (isRelaunching()) {
2020 return mLastContainsDismissKeyguardWindow;
2021 }
2022
Jorim Jaggife762342016-10-13 14:33:27 +02002023 for (int i = mChildren.size() - 1; i >= 0; i--) {
2024 if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
2025 return true;
2026 }
2027 }
2028 return false;
2029 }
2030
2031 boolean containsShowWhenLockedWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002032 // When we are relaunching, it is possible for us to be unfrozen before our previous
2033 // windows have been added back. Using the cached value ensures that our previous
2034 // showWhenLocked preference is honored until relaunching is complete.
2035 if (isRelaunching()) {
2036 return mLastContainsShowWhenLockedWindow;
2037 }
2038
Jorim Jaggife762342016-10-13 14:33:27 +02002039 for (int i = mChildren.size() - 1; i >= 0; i--) {
2040 if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
2041 return true;
2042 }
2043 }
Bryce Lee081554b2017-05-25 07:52:12 -07002044
Jorim Jaggife762342016-10-13 14:33:27 +02002045 return false;
2046 }
2047
2048 void checkKeyguardFlagsChanged() {
2049 final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
2050 final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
2051 if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
2052 || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002053 mWmService.notifyKeyguardFlagsChanged(null /* callback */,
lumark588a3e82018-07-20 18:53:54 +08002054 getDisplayContent().getDisplayId());
Jorim Jaggife762342016-10-13 14:33:27 +02002055 }
2056 mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
2057 mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
2058 }
2059
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002060 WindowState getImeTargetBelowWindow(WindowState w) {
2061 final int index = mChildren.indexOf(w);
2062 if (index > 0) {
2063 final WindowState target = mChildren.get(index - 1);
2064 if (target.canBeImeTarget()) {
2065 return target;
2066 }
2067 }
2068 return null;
2069 }
2070
2071 WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
2072 WindowState candidate = null;
2073 for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
2074 final WindowState w = mChildren.get(i);
2075 if (w.mRemoved) {
2076 continue;
2077 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02002078 if (candidate == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002079 candidate = w;
2080 }
2081 }
2082 return candidate;
2083 }
2084
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002085 /**
2086 * See {@link Activity#setDisablePreviewScreenshots}.
2087 */
2088 void setDisablePreviewScreenshots(boolean disable) {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002089 mDisablePreviewScreenshots = disable;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002090 }
2091
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002092 /**
chaviwd3bf08d2017-08-01 17:24:59 -07002093 * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
2094 */
2095 void setCanTurnScreenOn(boolean canTurnScreenOn) {
2096 mCanTurnScreenOn = canTurnScreenOn;
2097 }
2098
2099 /**
2100 * Indicates whether the current launch can turn the screen on. This is to prevent multiple
2101 * relayouts from turning the screen back on. The screen should only turn on at most
2102 * once per activity resume.
2103 *
2104 * @return true if the screen can be turned on.
2105 */
2106 boolean canTurnScreenOn() {
2107 return mCanTurnScreenOn;
2108 }
2109
2110 /**
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002111 * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
2112 * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
2113 * we can't take a snapshot for other reasons, for example, if we have a secure window.
2114 *
2115 * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
2116 * screenshot.
2117 */
2118 boolean shouldUseAppThemeSnapshot() {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002119 return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002120 true /* topToBottom */);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002121 }
2122
Jorim Jaggibe418292018-03-26 16:14:12 +02002123 SurfaceControl getAppAnimationLayer() {
Jorim Jaggi391790622018-04-18 15:30:44 +02002124 return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
2125 : needsZBoost() ? ANIMATION_LAYER_BOOSTED
2126 : ANIMATION_LAYER_STANDARD);
Jorim Jaggibe418292018-03-26 16:14:12 +02002127 }
2128
chaviw23ee71c2017-12-18 11:29:41 -08002129 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +01002130 public SurfaceControl getAnimationLeashParent() {
Robert Carrb9506032018-02-13 13:54:00 -08002131 // All normal app transitions take place in an animation layer which is below the pinned
2132 // stack but may be above the parent stacks of the given animating apps.
2133 // For transitions in the pinned stack (menu activity) we just let them occur as a child
2134 // of the pinned stack.
2135 if (!inPinnedWindowingMode()) {
2136 return getAppAnimationLayer();
2137 } else {
2138 return getStack().getSurfaceControl();
2139 }
chaviw23ee71c2017-12-18 11:29:41 -08002140 }
2141
Jorim Jaggic6976f02018-04-18 16:31:07 +02002142 private boolean shouldAnimate(int transit) {
2143 final boolean isSplitScreenPrimary =
2144 getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
2145 final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
2146
2147 // We animate always if it's not split screen primary, and only some special cases in split
2148 // screen primary because it causes issues with stack clipping when we run an un-minimize
2149 // animation at the same time.
2150 return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
2151 }
2152
Vishnu Naira2977262018-07-26 13:31:26 -07002153 /**
2154 * Creates a layer to apply crop to an animation.
2155 */
2156 private SurfaceControl createAnimationBoundsLayer(Transaction t) {
2157 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
2158 final SurfaceControl.Builder builder = makeAnimationLeash()
2159 .setParent(getAnimationLeashParent())
Vishnu Naire86bd982018-11-28 13:23:17 -08002160 .setName(getSurfaceControl() + " - animation-bounds");
Vishnu Naira2977262018-07-26 13:31:26 -07002161 final SurfaceControl boundsLayer = builder.build();
2162 t.show(boundsLayer);
2163 return boundsLayer;
2164 }
2165
Riddle Hsua118b3a2018-10-11 22:05:06 +08002166 /** Get position and crop region of animation. */
2167 @VisibleForTesting
2168 void getAnimationBounds(Point outPosition, Rect outBounds) {
2169 outPosition.set(0, 0);
2170 outBounds.setEmpty();
2171
2172 final TaskStack stack = getStack();
2173 final Task task = getTask();
2174 if (task != null && task.inFreeformWindowingMode()) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002175 task.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002176 } else if (stack != null) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002177 stack.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002178 }
2179
2180 // Always use stack bounds in order to have the ability to animate outside the task region.
2181 // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
2182 // according to the bounds.
2183 if (stack != null) {
2184 stack.getBounds(outBounds);
2185 }
2186 // We have the relative position so the local position can be removed from bounds.
2187 outBounds.offsetTo(0, 0);
2188 }
2189
Evan Roskyed6767f2018-10-26 17:21:06 -07002190 @Override
2191 Rect getDisplayedBounds() {
2192 final Task task = getTask();
2193 if (task != null) {
2194 final Rect overrideDisplayedBounds = task.getOverrideDisplayedBounds();
2195 if (!overrideDisplayedBounds.isEmpty()) {
2196 return overrideDisplayedBounds;
2197 }
2198 }
2199 return getBounds();
2200 }
2201
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002202 boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
2203 boolean isVoiceInteraction) {
2204
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002205 if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002206 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Jorim Jaggic6976f02018-04-18 16:31:07 +02002207 Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
2208 + " atoken=" + this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002209 }
2210 cancelAnimation();
2211 return false;
2212 }
2213
2214 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
2215 // to animate and it can cause strange artifacts when we unfreeze the display if some
2216 // different animation is running.
2217 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
2218 if (okToAnimate()) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002219 final AnimationAdapter adapter;
Riddle Hsua118b3a2018-10-11 22:05:06 +08002220 getAnimationBounds(mTmpPoint, mTmpRect);
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002221
2222 // Delaying animation start isn't compatible with remote animations at all.
lumark588a3e82018-07-20 18:53:54 +08002223 if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002224 && !mSurfaceAnimator.isAnimationStartDelayed()) {
lumark588a3e82018-07-20 18:53:54 +08002225 adapter = getDisplayContent().mAppTransition.getRemoteAnimationController()
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002226 .createAnimationAdapter(this, mTmpPoint, mTmpRect);
2227 } else {
lumark588a3e82018-07-20 18:53:54 +08002228 final int appStackClipMode =
2229 getDisplayContent().mAppTransition.getAppStackClipMode();
Vishnu Naira2977262018-07-26 13:31:26 -07002230 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
2231
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002232 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
2233 if (a != null) {
2234 adapter = new LocalAnimationAdapter(
2235 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
lumark588a3e82018-07-20 18:53:54 +08002236 getDisplayContent().mAppTransition.canSkipFirstFrame(),
Vishnu Naira2977262018-07-26 13:31:26 -07002237 appStackClipMode,
Jorim Jaggiaa763cd2018-03-22 23:20:36 +01002238 true /* isAppAnimation */),
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002239 mWmService.mSurfaceAnimationRunner);
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002240 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
2241 mNeedsZBoost = true;
2242 }
2243 mTransit = transit;
lumark588a3e82018-07-20 18:53:54 +08002244 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002245 } else {
2246 adapter = null;
chaviw23ee71c2017-12-18 11:29:41 -08002247 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002248 }
2249 if (adapter != null) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002250 startAnimation(getPendingTransaction(), adapter, !isVisible());
Jorim Jaggi82c17862018-02-21 17:50:18 +01002251 if (adapter.getShowWallpaper()) {
2252 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2253 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002254 }
2255 } else {
2256 cancelAnimation();
2257 }
2258 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2259
2260 return isReallyAnimating();
2261 }
2262
2263 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
2264 boolean isVoiceInteraction) {
2265 final DisplayContent displayContent = getTask().getDisplayContent();
2266 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2267 final int width = displayInfo.appWidth;
2268 final int height = displayInfo.appHeight;
2269 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
2270 "applyAnimation: atoken=" + this);
2271
2272 // Determine the visible rect to calculate the thumbnail clip
2273 final WindowState win = findMainWindow();
2274 final Rect frame = new Rect(0, 0, width, height);
2275 final Rect displayFrame = new Rect(0, 0,
2276 displayInfo.logicalWidth, displayInfo.logicalHeight);
2277 final Rect insets = new Rect();
2278 final Rect stableInsets = new Rect();
2279 Rect surfaceInsets = null;
2280 final boolean freeform = win != null && win.inFreeformWindowingMode();
2281 if (win != null) {
2282 // Containing frame will usually cover the whole screen, including dialog windows.
2283 // For freeform workspace windows it will not cover the whole screen and it also
2284 // won't exactly match the final freeform window frame (e.g. when overlapping with
2285 // the status bar). In that case we need to use the final frame.
2286 if (freeform) {
chaviw492139a2018-07-16 16:07:35 -07002287 frame.set(win.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01002288 } else if (win.isLetterboxedAppWindow()) {
2289 frame.set(getTask().getBounds());
Winson Chungc1674272018-02-21 10:15:17 -08002290 } else if (win.isDockedResizing()) {
2291 // If we are animating while docked resizing, then use the stack bounds as the
2292 // animation target (which will be different than the task bounds)
2293 frame.set(getTask().getParent().getBounds());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002294 } else {
chaviw553b0212018-07-12 13:37:01 -07002295 frame.set(win.getContainingFrame());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002296 }
2297 surfaceInsets = win.getAttrs().surfaceInsets;
Adrian Roos20e07892018-02-23 19:12:01 +01002298 // XXX(b/72757033): These are insets relative to the window frame, but we're really
2299 // interested in the insets relative to the frame we chose in the if-blocks above.
chaviw9c81e632018-07-31 11:17:52 -07002300 win.getContentInsets(insets);
2301 win.getStableInsets(stableInsets);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002302 }
2303
2304 if (mLaunchTaskBehind) {
2305 // Differentiate the two animations. This one which is briefly on the screen
2306 // gets the !enter animation, and the other activity which remains on the
2307 // screen gets the enter animation. Both appear in the mOpeningApps set.
2308 enter = false;
2309 }
2310 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
2311 + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
2312 + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
2313 final Configuration displayConfig = displayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002314 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002315 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
2316 surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
2317 if (a != null) {
2318 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
2319 final int containingWidth = frame.width();
2320 final int containingHeight = frame.height();
2321 a.initialize(containingWidth, containingHeight, width, height);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002322 a.scaleCurrentDuration(mWmService.getTransitionAnimationScaleLocked());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002323 }
2324 return a;
2325 }
2326
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002327 @Override
Jorim Jaggi6de61012018-03-19 14:53:23 +01002328 public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
2329 return mAnimatingAppWindowTokenRegistry != null
2330 && mAnimatingAppWindowTokenRegistry.notifyAboutToFinish(
2331 this, endDeferFinishCallback);
2332 }
2333
2334 @Override
2335 public void onAnimationLeashDestroyed(Transaction t) {
2336 super.onAnimationLeashDestroyed(t);
Vishnu Naira2977262018-07-26 13:31:26 -07002337 if (mAnimationBoundsLayer != null) {
2338 t.destroy(mAnimationBoundsLayer);
2339 mAnimationBoundsLayer = null;
2340 }
2341
Jorim Jaggi6de61012018-03-19 14:53:23 +01002342 if (mAnimatingAppWindowTokenRegistry != null) {
2343 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
2344 }
2345 }
2346
2347 @Override
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002348 protected void setLayer(Transaction t, int layer) {
2349 if (!mSurfaceAnimator.hasLeash()) {
2350 t.setLayer(mSurfaceControl, layer);
2351 }
2352 }
2353
2354 @Override
2355 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
2356 if (!mSurfaceAnimator.hasLeash()) {
2357 t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
2358 }
2359 }
2360
2361 @Override
2362 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
2363 if (!mSurfaceAnimator.hasLeash()) {
2364 t.reparent(mSurfaceControl, newParent.getHandle());
2365 }
2366 }
2367
2368 @Override
2369 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002370 // The leash is parented to the animation layer. We need to preserve the z-order by using
2371 // the prefix order index, but we boost if necessary.
Robert Carrb9506032018-02-13 13:54:00 -08002372 int layer = 0;
2373 if (!inPinnedWindowingMode()) {
2374 layer = getPrefixOrderIndex();
2375 } else {
2376 // Pinned stacks have animations take place within themselves rather than an animation
2377 // layer so we need to preserve the order relative to the stack (e.g. the order of our
2378 // task/parent).
2379 layer = getParent().getPrefixOrderIndex();
2380 }
2381
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002382 if (mNeedsZBoost) {
2383 layer += Z_BOOST_BASE;
2384 }
2385 leash.setLayer(layer);
Robert Carr2f8aa392018-01-31 14:46:51 -08002386
2387 final DisplayContent dc = getDisplayContent();
Jorim Jaggibe418292018-03-26 16:14:12 +02002388 dc.assignStackOrdering();
Jorim Jaggi6de61012018-03-19 14:53:23 +01002389 if (mAnimatingAppWindowTokenRegistry != null) {
2390 mAnimatingAppWindowTokenRegistry.notifyStarting(this);
2391 }
Vishnu Naira2977262018-07-26 13:31:26 -07002392
2393 // If the animation needs to be cropped then an animation bounds layer is created as a child
2394 // of the pinned stack or animation layer. The leash is then reparented to this new layer.
2395 if (mNeedsAnimationBoundsLayer) {
2396 final TaskStack stack = getStack();
2397 if (stack == null) {
2398 return;
2399 }
2400 mAnimationBoundsLayer = createAnimationBoundsLayer(t);
2401
2402 // Set clip rect to stack bounds.
2403 mTmpRect.setEmpty();
2404 stack.getBounds(mTmpRect);
2405
2406 // Crop to stack bounds.
2407 t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
2408
2409 // Reparent leash to animation bounds layer.
2410 t.reparent(leash, mAnimationBoundsLayer.getHandle());
2411 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002412 }
2413
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002414 /**
2415 * This must be called while inside a transaction.
2416 */
2417 void showAllWindowsLocked() {
2418 forAllWindows(windowState -> {
2419 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + windowState);
2420 windowState.performShowLocked();
2421 }, false /* traverseTopToBottom */);
Jorim Jaggia5e10572017-11-15 14:36:26 +01002422 }
2423
2424 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002425 protected void onAnimationFinished() {
2426 super.onAnimationFinished();
2427
2428 mTransit = TRANSIT_UNSET;
2429 mTransitFlags = 0;
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002430 mNeedsZBoost = false;
Vishnu Naira2977262018-07-26 13:31:26 -07002431 mNeedsAnimationBoundsLayer = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002432
2433 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
2434 "AppWindowToken");
2435
Jorim Jaggi988f6682017-11-17 17:46:43 +01002436 clearThumbnail();
Jorim Jaggi752cd822018-03-29 16:29:18 +02002437 setClientHidden(isHidden() && hiddenRequested);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002438
lumarkff0ab692018-11-05 20:32:30 +08002439 getDisplayContent().computeImeTargetIfNeeded(this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002440
2441 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this
2442 + ": reportedVisible=" + reportedVisible
2443 + " okToDisplay=" + okToDisplay()
2444 + " okToAnimate=" + okToAnimate()
2445 + " startingDisplayed=" + startingDisplayed);
2446
2447 // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
2448 // traverse the copy.
2449 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
2450 children.forEach(WindowState::onExitAnimationDone);
2451
lumark588a3e82018-07-20 18:53:54 +08002452 getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002453 scheduleAnimation();
2454 }
2455
2456 @Override
2457 boolean isAppAnimating() {
2458 return isSelfAnimating();
2459 }
2460
2461 @Override
2462 boolean isSelfAnimating() {
2463 // If we are about to start a transition, we also need to be considered animating.
2464 return isWaitingForTransitionStart() || isReallyAnimating();
2465 }
2466
2467 /**
2468 * @return True if and only if we are actually running an animation. Note that
2469 * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
2470 * start.
2471 */
2472 private boolean isReallyAnimating() {
2473 return super.isSelfAnimating();
2474 }
2475
Jorim Jaggi988f6682017-11-17 17:46:43 +01002476 @Override
2477 void cancelAnimation() {
2478 super.cancelAnimation();
2479 clearThumbnail();
2480 }
2481
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002482 boolean isWaitingForTransitionStart() {
lumark588a3e82018-07-20 18:53:54 +08002483 return getDisplayContent().mAppTransition.isTransitionSet()
2484 && (getDisplayContent().mOpeningApps.contains(this)
2485 || getDisplayContent().mClosingApps.contains(this));
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002486 }
2487
2488 public int getTransit() {
2489 return mTransit;
2490 }
2491
2492 int getTransitFlags() {
2493 return mTransitFlags;
2494 }
2495
Jorim Jaggi988f6682017-11-17 17:46:43 +01002496 void attachThumbnailAnimation() {
2497 if (!isReallyAnimating()) {
2498 return;
2499 }
2500 final int taskId = getTask().mTaskId;
2501 final GraphicBuffer thumbnailHeader =
lumark588a3e82018-07-20 18:53:54 +08002502 getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002503 if (thumbnailHeader == null) {
2504 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
2505 return;
2506 }
2507 clearThumbnail();
2508 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
2509 mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
2510 }
2511
Tony Mak64b8d562017-12-28 17:44:02 +00002512 /**
2513 * Attaches a surface with a thumbnail for the
2514 * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
2515 */
2516 void attachCrossProfileAppsThumbnailAnimation() {
2517 if (!isReallyAnimating()) {
2518 return;
2519 }
2520 clearThumbnail();
2521
2522 final WindowState win = findMainWindow();
2523 if (win == null) {
2524 return;
2525 }
chaviw492139a2018-07-16 16:07:35 -07002526 final Rect frame = win.getFrameLw();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002527 final int thumbnailDrawableRes = getTask().mUserId == mWmService.mCurrentUserId
Tony Mak64b8d562017-12-28 17:44:02 +00002528 ? R.drawable.ic_account_circle
Tony Makda4af232018-04-27 11:01:10 +01002529 : R.drawable.ic_corp_badge;
Tony Mak64b8d562017-12-28 17:44:02 +00002530 final GraphicBuffer thumbnail =
lumark588a3e82018-07-20 18:53:54 +08002531 getDisplayContent().mAppTransition
Tony Mak64b8d562017-12-28 17:44:02 +00002532 .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
2533 if (thumbnail == null) {
2534 return;
2535 }
2536 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
2537 final Animation animation =
lumark588a3e82018-07-20 18:53:54 +08002538 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
chaviw492139a2018-07-16 16:07:35 -07002539 win.getFrameLw());
Tony Mak64b8d562017-12-28 17:44:02 +00002540 mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
2541 frame.top));
2542 }
2543
Jorim Jaggi988f6682017-11-17 17:46:43 +01002544 private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
2545 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
2546
2547 // If this is a multi-window scenario, we use the windows frame as
2548 // destination of the thumbnail header animation. If this is a full screen
2549 // window scenario, we use the whole display as the target.
2550 WindowState win = findMainWindow();
2551 Rect appRect = win != null ? win.getContentFrameLw() :
2552 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
chaviw9c81e632018-07-31 11:17:52 -07002553 final Rect insets = win != null ? win.getContentInsets() : null;
Jorim Jaggi988f6682017-11-17 17:46:43 +01002554 final Configuration displayConfig = mDisplayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002555 return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
Jorim Jaggi988f6682017-11-17 17:46:43 +01002556 appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
2557 displayConfig.orientation);
2558 }
2559
2560 private void clearThumbnail() {
2561 if (mThumbnail == null) {
2562 return;
2563 }
2564 mThumbnail.destroy();
2565 mThumbnail = null;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002566 }
2567
Jorim Jaggif84e2f62018-01-16 14:17:59 +01002568 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
2569 mRemoteAnimationDefinition = definition;
2570 }
2571
2572 RemoteAnimationDefinition getRemoteAnimationDefinition() {
2573 return mRemoteAnimationDefinition;
2574 }
2575
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002576 @Override
2577 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2578 super.dump(pw, prefix, dumpAll);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002579 if (appToken != null) {
Wale Ogunwale72919d22016-12-08 18:58:50 -08002580 pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002581 }
Winson Chung48b25652018-10-22 14:04:30 -07002582 pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08002583 pw.print(prefix); pw.print("task="); pw.println(getTask());
Wale Ogunwale51362492016-09-08 17:49:17 -07002584 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
2585 pw.print(" mOrientation="); pw.println(mOrientation);
Wale Ogunwale89973222017-04-23 18:39:45 -07002586 pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
2587 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
2588 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07002589 if (paused) {
2590 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002591 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08002592 if (mAppStopped) {
2593 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
2594 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002595 if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002596 || allDrawn || mLastAllDrawn) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002597 pw.print(prefix); pw.print("mNumInterestingWindows=");
2598 pw.print(mNumInterestingWindows);
2599 pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002600 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07002601 pw.print(" allDrawn="); pw.print(allDrawn);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002602 pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
Craig Mautner6fbda632012-07-03 09:26:39 -07002603 pw.println(")");
2604 }
2605 if (inPendingTransaction) {
2606 pw.print(prefix); pw.print("inPendingTransaction=");
2607 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002608 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08002609 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002610 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
2611 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08002612 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08002613 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002614 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002615 if (startingWindow != null || startingSurface != null
Wale Ogunwale6c459212017-05-17 08:56:03 -07002616 || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002617 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002618 pw.print(" startingSurface="); pw.print(startingSurface);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002619 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale6c459212017-05-17 08:56:03 -07002620 pw.print(" startingMoved="); pw.print(startingMoved);
2621 pw.println(" mHiddenSetFromTransferredStartingWindow="
2622 + mHiddenSetFromTransferredStartingWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002623 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01002624 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08002625 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002626 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08002627 }
2628 if (mPendingRelaunchCount != 0) {
2629 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01002630 }
Wale Ogunwalee287e192017-04-21 09:30:12 -07002631 if (mRemovingFromDisplay) {
2632 pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
2633 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002634 }
2635
2636 @Override
2637 void setHidden(boolean hidden) {
2638 super.setHidden(hidden);
Winson Chunge55c0192017-08-24 14:50:48 -07002639
2640 if (hidden) {
2641 // Once the app window is hidden, reset the last saved PiP snap fraction
2642 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
2643 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002644 scheduleAnimation();
2645 }
2646
2647 @Override
2648 void prepareSurfaces() {
2649 // isSelfAnimating also returns true when we are about to start a transition, so we need
2650 // to check super here.
2651 final boolean reallyAnimating = super.isSelfAnimating();
2652 final boolean show = !isHidden() || reallyAnimating;
2653 if (show && !mLastSurfaceShowing) {
2654 mPendingTransaction.show(mSurfaceControl);
2655 } else if (!show && mLastSurfaceShowing) {
2656 mPendingTransaction.hide(mSurfaceControl);
Jorim Jaggi4d1835d2017-08-31 17:28:27 +02002657 }
Jorim Jaggi988f6682017-11-17 17:46:43 +01002658 if (mThumbnail != null) {
2659 mThumbnail.setShowing(mPendingTransaction, show);
2660 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002661 mLastSurfaceShowing = show;
2662 super.prepareSurfaces();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002663 }
2664
Jorim Jaggi77d0f36c2018-03-16 17:49:49 +01002665 /**
2666 * @return Whether our {@link #getSurfaceControl} is currently showing.
2667 */
2668 boolean isSurfaceShowing() {
2669 return mLastSurfaceShowing;
2670 }
2671
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002672 boolean isFreezingScreen() {
2673 return mFreezingScreen;
2674 }
2675
2676 @Override
2677 boolean needsZBoost() {
2678 return mNeedsZBoost || super.needsZBoost();
2679 }
2680
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07002681 @CallSuper
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002682 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02002683 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07002684 final long token = proto.start(fieldId);
2685 writeNameToProto(proto, NAME);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002686 super.writeToProto(proto, WINDOW_TOKEN, trim);
Vishnu Nair04ab4392018-01-10 11:00:06 -08002687 proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
2688 proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
2689 proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
2690 if (mThumbnail != null){
2691 mThumbnail.writeToProto(proto, THUMBNAIL);
2692 }
2693 proto.write(FILLS_PARENT, mFillsParent);
2694 proto.write(APP_STOPPED, mAppStopped);
2695 proto.write(HIDDEN_REQUESTED, hiddenRequested);
2696 proto.write(CLIENT_HIDDEN, mClientHidden);
2697 proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
2698 proto.write(REPORTED_DRAWN, reportedDrawn);
2699 proto.write(REPORTED_VISIBLE, reportedVisible);
2700 proto.write(NUM_INTERESTING_WINDOWS, mNumInterestingWindows);
2701 proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
2702 proto.write(ALL_DRAWN, allDrawn);
2703 proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
2704 proto.write(REMOVED, removed);
2705 if (startingWindow != null){
2706 startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
2707 }
2708 proto.write(STARTING_DISPLAYED, startingDisplayed);
2709 proto.write(STARTING_MOVED, startingMoved);
2710 proto.write(HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW,
2711 mHiddenSetFromTransferredStartingWindow);
2712 for (Rect bounds : mFrozenBounds) {
2713 bounds.writeToProto(proto, FROZEN_BOUNDS);
2714 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002715 proto.end(token);
2716 }
2717
2718 void writeNameToProto(ProtoOutputStream proto, long fieldId) {
2719 if (appToken == null) {
2720 return;
2721 }
2722 try {
2723 proto.write(fieldId, appToken.getName());
2724 } catch (RemoteException e) {
2725 // This shouldn't happen, but in this case fall back to outputting nothing
2726 Slog.e(TAG, e.toString());
2727 }
2728 }
2729
2730 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002731 public String toString() {
2732 if (stringName == null) {
2733 StringBuilder sb = new StringBuilder();
2734 sb.append("AppWindowToken{");
2735 sb.append(Integer.toHexString(System.identityHashCode(this)));
2736 sb.append(" token="); sb.append(token); sb.append('}');
2737 stringName = sb.toString();
2738 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002739 return stringName + ((mIsExiting) ? " mIsExiting=" : "");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002740 }
Adrian Roos20e07892018-02-23 19:12:01 +01002741
2742 Rect getLetterboxInsets() {
2743 if (mLetterbox != null) {
2744 return mLetterbox.getInsets();
2745 } else {
2746 return new Rect();
2747 }
2748 }
Adrian Roos23df3a32018-03-15 15:41:13 +01002749
2750 /**
2751 * @eturn true if there is a letterbox and any part of that letterbox overlaps with
2752 * the given {@code rect}.
2753 */
2754 boolean isLetterboxOverlappingWith(Rect rect) {
2755 return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
2756 }
chaviw4ad54912018-05-30 11:05:44 -07002757
2758 /**
2759 * Sets if this AWT is in the process of closing or entering PIP.
2760 * {@link #mWillCloseOrEnterPip}}
2761 */
2762 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
2763 mWillCloseOrEnterPip = willCloseOrEnterPip;
2764 }
2765
2766 /**
2767 * Returns whether this AWT is considered closing. Conditions are either
2768 * 1. Is this app animating and was requested to be hidden
2769 * 2. App is delayed closing since it might enter PIP.
2770 */
2771 boolean isClosingOrEnteringPip() {
2772 return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
2773 }
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +02002774
2775 /**
2776 * @return Whether we are allowed to show non-starting windows at the moment. We disallow
2777 * showing windows during transitions in case we have windows that have wide-color-gamut
2778 * color mode set to avoid jank in the middle of the transition.
2779 */
2780 boolean canShowWindows() {
2781 return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
2782 }
2783
2784 /**
2785 * @return true if we have a window that has a non-default color mode set; false otherwise.
2786 */
2787 private boolean hasNonDefaultColorWindow() {
2788 return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
2789 true /* topToBottom */);
2790 }
lumark588a3e82018-07-20 18:53:54 +08002791
2792 void removeFromPendingTransition() {
2793 if (isWaitingForTransitionStart() && mDisplayContent != null) {
2794 mDisplayContent.mOpeningApps.remove(this);
2795 mDisplayContent.mClosingApps.remove(this);
2796 }
2797 }
Jeff Browne9bdb312012-04-05 15:30:10 -07002798}