blob: d8b2b5200f0c10de19f901e46e44bc32a7576601 [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;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080094import android.os.Build;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -080095import android.os.Debug;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070096import android.os.IBinder;
Steven Timotiusaf03df62017-07-18 16:56:43 -070097import android.os.RemoteException;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080098import android.os.SystemClock;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020099import android.os.Trace;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800100import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700101import android.util.proto.ProtoOutputStream;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200102import android.view.DisplayInfo;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800103import android.view.IApplicationToken;
Robert Carr788f5742018-07-30 17:46:45 -0700104import android.view.InputApplicationHandle;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100105import android.view.RemoteAnimationDefinition;
Robert Carr6914f082017-03-20 19:04:30 -0700106import android.view.SurfaceControl;
Tony Mak64b8d562017-12-28 17:44:02 +0000107import android.view.SurfaceControl.Transaction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800108import android.view.WindowManager;
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200109import android.view.WindowManager.LayoutParams;
Tony Mak64b8d562017-12-28 17:44:02 +0000110import android.view.animation.Animation;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800111
Tony Mak64b8d562017-12-28 17:44:02 +0000112import com.android.internal.R;
Riddle Hsua118b3a2018-10-11 22:05:06 +0800113import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800114import com.android.internal.util.ToBooleanFunction;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800115import com.android.server.AttributeCache;
116import com.android.server.policy.WindowManagerPolicy;
Adrian Roose99bc052017-11-20 17:55:31 +0100117import com.android.server.policy.WindowManagerPolicy.StartingSurface;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800118import com.android.server.wm.WindowManagerService.H;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800119
120import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +0100121import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800122import java.util.ArrayList;
lumark588a3e82018-07-20 18:53:54 +0800123import java.util.function.Consumer;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800124
125class AppTokenList extends ArrayList<AppWindowToken> {
126}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800127
128/**
129 * Version of WindowToken that is specifically for a particular application (or
130 * really activity) that is displaying windows.
131 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800132class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener,
133 ConfigurationContainerListener {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800134 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
135
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100136 /**
137 * Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
138 */
139 private static final int Z_BOOST_BASE = 800570000;
140
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800141 // Non-null only for application tokens.
142 final IApplicationToken appToken;
Winson Chung48b25652018-10-22 14:04:30 -0700143 final ComponentName mActivityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800144 final boolean mVoiceInteraction;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700145
Wale Ogunwale51362492016-09-08 17:49:17 -0700146 /** @see WindowContainer#fillsParent() */
147 private boolean mFillsParent;
Craig Mautner4c5eb222013-11-18 12:59:05 -0800148 boolean layoutConfigChanges;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800149 boolean mShowForAllUsers;
150 int mTargetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -0700151
Bryce Lee6d410262017-02-28 15:30:17 -0800152 // Flag set while reparenting to prevent actions normally triggered by an individual parent
153 // change.
154 private boolean mReparenting;
155
Wale Ogunwalee287e192017-04-21 09:30:12 -0700156 // True if we are current in the process of removing this app token from the display
157 private boolean mRemovingFromDisplay = false;
158
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800159 // The input dispatching timeout for this application token in nanoseconds.
Wale Ogunwale72919d22016-12-08 18:58:50 -0800160 long mInputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800161
162 // These are used for determining when all windows associated with
163 // an activity have been drawn, so they can be made visible together
164 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -0700165 // initialize so that it doesn't match mTransactionSequence which is an int.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700166 private long mLastTransactionSequence = Long.MIN_VALUE;
167 private int mNumInterestingWindows;
168 private int mNumDrawnWindows;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800169 boolean inPendingTransaction;
170 boolean allDrawn;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000171 private boolean mLastAllDrawn;
172
Craig Mautner7636dfb2012-11-16 15:24:11 -0800173 // Set to true when this app creates a surface while in the middle of an animation. In that
174 // case do not clear allDrawn until the animation completes.
175 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800176
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800177 // Is this window's surface needed? This is almost like hidden, except
178 // it will sometimes be true a little earlier: when the token has
179 // been shown, but is still waiting for its app transition to execute
180 // before making its windows shown.
181 boolean hiddenRequested;
182
183 // Have we told the window clients to hide themselves?
Wale Ogunwale89973222017-04-23 18:39:45 -0700184 private boolean mClientHidden;
185
186 // If true we will defer setting mClientHidden to true and reporting to the client that it is
187 // hidden.
188 boolean mDeferHidingClient;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800189
190 // Last visibility state we reported to the app token.
191 boolean reportedVisible;
192
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700193 // Last drawn state we reported to the app token.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700194 private boolean reportedDrawn;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700195
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800196 // Set to true when the token has been removed from the window mgr.
197 boolean removed;
198
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800199 // Information about an application starting window if displayed.
200 StartingData startingData;
201 WindowState startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800202 StartingSurface startingSurface;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800203 boolean startingDisplayed;
204 boolean startingMoved;
Jorim Jaggi60f9c972018-02-01 19:21:07 +0100205
Wale Ogunwale6c459212017-05-17 08:56:03 -0700206 // True if the hidden state of this token was forced to false due to a transferred starting
207 // window.
208 private boolean mHiddenSetFromTransferredStartingWindow;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800209 boolean firstWindowDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700210 private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
211 new WindowState.UpdateReportedVisibilityResults();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800212
213 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700214 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800215
Wale Ogunwale571771c2016-08-26 13:18:50 -0700216 // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
Craig Mautner799bc1d2015-01-14 10:33:48 -0800217 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800218
Craig Mautnerbb742462014-07-07 15:28:55 -0700219 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700220 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700221
Wale Ogunwale72919d22016-12-08 18:58:50 -0800222 private boolean mAlwaysFocusable;
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800223
Robert Carre12aece2016-02-02 22:43:27 -0800224 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700225 int mRotationAnimationHint;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700226 private int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800227
Jorim Jaggife762342016-10-13 14:33:27 +0200228 private boolean mLastContainsShowWhenLockedWindow;
229 private boolean mLastContainsDismissKeyguardWindow;
230
Jorim Jaggi0429f352015-12-22 16:29:16 +0100231 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700232 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100233
Wale Ogunwale6c459212017-05-17 08:56:03 -0700234 private boolean mDisablePreviewScreenshots;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +0100235
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700236 private Task mLastParent;
Robert Carred3e83b2017-04-21 13:26:55 -0700237
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800238 // TODO: Remove after unification
239 ActivityRecord mActivityRecord;
240
chaviwd3bf08d2017-08-01 17:24:59 -0700241 /**
242 * See {@link #canTurnScreenOn()}
243 */
244 private boolean mCanTurnScreenOn = true;
245
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200246 /**
247 * If we are running an animation, this determines the transition type. Must be one of
248 * AppTransition.TRANSIT_* constants.
249 */
250 private int mTransit;
251
252 /**
253 * If we are running an animation, this determines the flags during this animation. Must be a
254 * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
255 */
256 private int mTransitFlags;
257
258 /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
Jorim Jaggifd1891462017-12-29 15:41:36 +0100259 private boolean mLastSurfaceShowing = true;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200260
Jorim Jaggi988f6682017-11-17 17:46:43 +0100261 private AppWindowThumbnail mThumbnail;
262
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000263 /** Have we been asked to have this token keep the screen frozen? */
264 private boolean mFreezingScreen;
265
266 /** Whether this token should be boosted at the top of all app window tokens. */
267 private boolean mNeedsZBoost;
Adrian Roos4d18a2e2017-12-19 19:08:05 +0100268 private Letterbox mLetterbox;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000269
chaviw23ee71c2017-12-18 11:29:41 -0800270 private final Point mTmpPoint = new Point();
chaviw23012112017-12-20 15:29:04 -0800271 private final Rect mTmpRect = new Rect();
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100272 private RemoteAnimationDefinition mRemoteAnimationDefinition;
Jorim Jaggi6de61012018-03-19 14:53:23 +0100273 private AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry;
chaviw23ee71c2017-12-18 11:29:41 -0800274
chaviw4ad54912018-05-30 11:05:44 -0700275 /**
276 * A flag to determine if this AWT is in the process of closing or entering PIP. This is needed
277 * to help AWT know that the app is in the process of closing but hasn't yet started closing on
278 * the WM side.
279 */
280 private boolean mWillCloseOrEnterPip;
281
Vishnu Naira2977262018-07-26 13:31:26 -0700282 /** Layer used to constrain the animation to a token's stack bounds. */
283 SurfaceControl mAnimationBoundsLayer;
284
285 /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
286 boolean mNeedsAnimationBoundsLayer;
287
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800288 private static final int STARTING_WINDOW_TYPE_NONE = 0;
289 private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
290 private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
291
Winson Chung48b25652018-10-22 14:04:30 -0700292 AppWindowToken(WindowManagerService service, IApplicationToken token,
293 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
294 long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
295 int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
296 boolean launchTaskBehind, boolean alwaysFocusable,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800297 ActivityRecord activityRecord) {
Winson Chung48b25652018-10-22 14:04:30 -0700298 this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800299 // TODO: remove after unification
300 mActivityRecord = activityRecord;
301 mActivityRecord.registerConfigurationChangeListener(this);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800302 mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800303 mShowForAllUsers = showForAllUsers;
304 mTargetSdk = targetSdk;
305 mOrientation = orientation;
306 layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0;
307 mLaunchTaskBehind = launchTaskBehind;
308 mAlwaysFocusable = alwaysFocusable;
309 mRotationAnimationHint = rotationAnimationHint;
310
311 // Application tokens start out hidden.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200312 setHidden(true);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800313 hiddenRequested = true;
314 }
315
Winson Chung48b25652018-10-22 14:04:30 -0700316 AppWindowToken(WindowManagerService service, IApplicationToken token,
317 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
318 boolean fillsParent) {
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800319 super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
320 false /* ownerCanManageAppTokens */);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700321 appToken = token;
Winson Chung48b25652018-10-22 14:04:30 -0700322 mActivityComponent = activityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800323 mVoiceInteraction = voiceInteraction;
Wale Ogunwale17f175c2017-02-07 16:54:10 -0800324 mFillsParent = fillsParent;
Robert Carr0bcbe642018-10-11 19:07:43 -0700325 mInputApplicationHandle = new InputApplicationHandle(appToken.asBinder());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800326 }
327
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800328 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
329 firstWindowDrawn = true;
330
331 // We now have a good window to show, remove dead placeholders
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700332 removeDeadWindows();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800333
Jorim Jaggi02886a82016-12-06 09:10:06 -0800334 if (startingWindow != null) {
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800335 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
336 + win.mToken + ": first real window is shown, no animation");
337 // If this initial window is animating, stop it -- we will do an animation to reveal
338 // it from behind the starting window, so there is no need for it to also be doing its
339 // own stuff.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100340 win.cancelAnimation();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800341 removeStartingWindow();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800342 }
343 updateReportedVisibilityLocked();
344 }
345
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800346 void updateReportedVisibilityLocked() {
347 if (appToken == null) {
348 return;
349 }
350
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700351 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700352 final int count = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800353
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700354 mReportedVisibilityResults.reset();
355
356 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700357 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700358 win.updateReportedVisibility(mReportedVisibilityResults);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800359 }
360
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700361 int numInteresting = mReportedVisibilityResults.numInteresting;
362 int numVisible = mReportedVisibilityResults.numVisible;
363 int numDrawn = mReportedVisibilityResults.numDrawn;
364 boolean nowGone = mReportedVisibilityResults.nowGone;
365
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700366 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200367 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !isHidden();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700368 if (!nowGone) {
369 // If the app is not yet gone, then it can only become visible/drawn.
370 if (!nowDrawn) {
371 nowDrawn = reportedDrawn;
372 }
373 if (!nowVisible) {
374 nowVisible = reportedVisible;
375 }
376 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800377 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800378 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700379 if (nowDrawn != reportedDrawn) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800380 if (mActivityRecord != null) {
381 mActivityRecord.onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700382 }
383 reportedDrawn = nowDrawn;
384 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800385 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700386 if (DEBUG_VISIBILITY) Slog.v(TAG,
387 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800388 reportedVisible = nowVisible;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800389 if (mActivityRecord != null) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800390 if (nowVisible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800391 onWindowsVisible();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800392 } else {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800393 onWindowsGone();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800394 }
395 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800396 }
397 }
398
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800399 private void onWindowsGone() {
400 if (mActivityRecord == null) {
401 return;
402 }
403 if (DEBUG_VISIBILITY) {
404 Slog.v(TAG_WM, "Reporting gone in " + mActivityRecord.appToken);
405 }
406 mActivityRecord.onWindowsGone();
407 }
408
409 private void onWindowsVisible() {
410 if (mActivityRecord == null) {
411 return;
412 }
413 if (DEBUG_VISIBILITY) {
414 Slog.v(TAG_WM, "Reporting visible in " + mActivityRecord.appToken);
415 }
416 mActivityRecord.onWindowsVisible();
417 }
418
Wale Ogunwale89973222017-04-23 18:39:45 -0700419 boolean isClientHidden() {
420 return mClientHidden;
421 }
422
423 void setClientHidden(boolean hideClient) {
424 if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
425 return;
426 }
Jorim Jaggi067b5bf2018-02-23 17:42:39 +0100427 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
428 + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
Wale Ogunwale89973222017-04-23 18:39:45 -0700429 mClientHidden = hideClient;
430 sendAppVisibilityToClients();
431 }
432
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800433 void setVisibility(boolean visible, boolean deferHidingClient) {
434 final AppTransition appTransition = getDisplayContent().mAppTransition;
435
436 // Don't set visibility to false if we were already not visible. This prevents WM from
437 // adding the app to the closing app list which doesn't make sense for something that is
438 // already not visible. However, set visibility to true even if we are already visible.
439 // This makes sure the app is added to the opening apps list so that the right
440 // transition can be selected.
441 // TODO: Probably a good idea to separate the concept of opening/closing apps from the
442 // concept of setting visibility...
443 if (!visible && hiddenRequested) {
444
445 if (!deferHidingClient && mDeferHidingClient) {
446 // We previously deferred telling the client to hide itself when visibility was
447 // initially set to false. Now we would like it to hide, so go ahead and set it.
448 mDeferHidingClient = deferHidingClient;
449 setClientHidden(true);
450 }
451 return;
452 }
453
454 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
455 Slog.v(TAG_WM, "setAppVisibility("
456 + appToken + ", visible=" + visible + "): " + appTransition
457 + " hidden=" + isHidden() + " hiddenRequested="
458 + hiddenRequested + " Callers=" + Debug.getCallers(6));
459 }
460
461 final DisplayContent displayContent = getDisplayContent();
462 displayContent.mOpeningApps.remove(this);
463 displayContent.mClosingApps.remove(this);
464 waitingToShow = false;
465 hiddenRequested = !visible;
466 mDeferHidingClient = deferHidingClient;
467
468 if (!visible) {
469 // If the app is dead while it was visible, we kept its dead window on screen.
470 // Now that the app is going invisible, we can remove it. It will be restarted
471 // if made visible again.
472 removeDeadWindows();
473 } else {
474 if (!appTransition.isTransitionSet()
475 && appTransition.isReady()) {
476 // Add the app mOpeningApps if transition is unset but ready. This means
477 // we're doing a screen freeze, and the unfreeze will wait for all opening
478 // apps to be ready.
479 displayContent.mOpeningApps.add(this);
480 }
481 startingMoved = false;
482 // If the token is currently hidden (should be the common case), or has been
483 // stopped, then we need to set up to wait for its windows to be ready.
484 if (isHidden() || mAppStopped) {
485 clearAllDrawn();
486
487 // If the app was already visible, don't reset the waitingToShow state.
488 if (isHidden()) {
489 waitingToShow = true;
490 }
491 }
492
493 // In the case where we are making an app visible but holding off for a transition,
494 // we still need to tell the client to make its windows visible so they get drawn.
495 // Otherwise, we will wait on performing the transition until all windows have been
496 // drawn, they never will be, and we are sad.
497 setClientHidden(false);
498
499 requestUpdateWallpaperIfNeeded();
500
501 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + this);
502 mAppStopped = false;
503
504 transferStartingWindowFromHiddenAboveTokenIfNeeded();
505 }
506
507 // If we are preparing an app transition, then delay changing
508 // the visibility of this token until we execute that transition.
509 if (okToAnimate() && appTransition.isTransitionSet()) {
510 inPendingTransaction = true;
511 if (visible) {
512 displayContent.mOpeningApps.add(this);
513 mEnteringAnimation = true;
514 } else {
515 displayContent.mClosingApps.add(this);
516 mEnteringAnimation = false;
517 }
518 if (appTransition.getAppTransition()
519 == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
520 // We're launchingBehind, add the launching activity to mOpeningApps.
521 final WindowState win = getDisplayContent().findFocusedWindow();
522 if (win != null) {
523 final AppWindowToken focusedToken = win.mAppToken;
524 if (focusedToken != null) {
525 if (DEBUG_APP_TRANSITIONS) {
526 Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
527 + " adding " + focusedToken + " to mOpeningApps");
528 }
529 // Force animation to be loaded.
530 focusedToken.setHidden(true);
531 displayContent.mOpeningApps.add(focusedToken);
532 }
533 }
534 }
535 return;
536 }
537
538 commitVisibility(null, visible, TRANSIT_UNSET, true, mVoiceInteraction);
539 updateReportedVisibilityLocked();
540 }
541
542 boolean commitVisibility(WindowManager.LayoutParams lp,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700543 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
544
545 boolean delayed = false;
546 inPendingTransaction = false;
Wale Ogunwale9e4721f2017-05-23 19:37:30 -0700547 // Reset the state of mHiddenSetFromTransferredStartingWindow since visibility is actually
548 // been set by the app now.
549 mHiddenSetFromTransferredStartingWindow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700550
551 // Allow for state changes and animation to be applied if:
552 // * token is transitioning visibility state
553 // * or the token was marked as hidden and is exiting before we had a chance to play the
554 // transition animation
555 // * or this is an opening app and windows are being replaced.
556 boolean visibilityChanged = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200557 if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800558 final AccessibilityController accessibilityController =
559 mWmService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700560 boolean changed = false;
561 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200562 "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700563
564 boolean runningAppAnimation = false;
565
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100566 if (transit != WindowManager.TRANSIT_UNSET) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200567 if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700568 delayed = runningAppAnimation = true;
569 }
570 final WindowState window = findMainWindow();
571 //TODO (multidisplay): Magnification is supported only for the default display.
572 if (window != null && accessibilityController != null
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700573 && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700574 accessibilityController.onAppWindowTransitionLocked(window, transit);
575 }
576 changed = true;
577 }
578
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700579 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700580 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700581 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700582 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700583 }
584
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200585 setHidden(!visible);
586 hiddenRequested = !visible;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700587 visibilityChanged = true;
588 if (!visible) {
589 stopFreezingScreen(true, true);
590 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700591 // If we are being set visible, and the starting window is not yet displayed,
592 // then make sure it doesn't get displayed.
593 if (startingWindow != null && !startingWindow.isDrawnLw()) {
594 startingWindow.mPolicyVisibility = false;
595 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700596 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -0700597
598 // We are becoming visible, so better freeze the screen with the windows that are
599 // getting visible so we also wait for them.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800600 forAllWindows(mWmService::makeWindowFreezingScreenIfNeededLocked, true);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700601 }
602
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800603 if (DEBUG_APP_TRANSITIONS) {
604 Slog.v(TAG_WM, "commitVisibility: " + this
605 + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
606 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700607
608 if (changed) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800609 getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700610 if (performLayout) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800611 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700612 false /*updateInputWindows*/);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800613 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700614 }
Arthur Hung95b38a92018-07-20 18:56:12 +0800615 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700616 }
617 }
618
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200619 if (isReallyAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700620 delayed = true;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100621 } else {
622
623 // We aren't animating anything, but exiting windows rely on the animation finished
624 // callback being called in case the AppWindowToken was pretending to be animating,
625 // which we might have done because we were in closing/opening apps list.
626 onAnimationFinished();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700627 }
628
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700629 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100630 if ((mChildren.get(i)).isSelfOrChildAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700631 delayed = true;
632 }
633 }
634
635 if (visibilityChanged) {
636 if (visible && !delayed) {
637 // The token was made immediately visible, there will be no entrance animation.
638 // We need to inform the client the enter animation was finished.
639 mEnteringAnimation = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800640 mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(
641 token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700642 }
Robert Carr61b81112017-07-17 18:08:15 -0700643
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800644 // If we're becoming visible, immediately change client visibility as well. there seem
645 // to be some edge cases where we change our visibility but client visibility never gets
646 // updated.
Jorim Jaggi110839b2018-01-22 12:49:04 +0100647 // If we're becoming invisible, update the client visibility if we are not running an
648 // animation. Otherwise, we'll update client visibility in onAnimationFinished.
Jorim Jaggi3cad57f2018-02-20 18:32:01 +0100649 if (visible || !isReallyAnimating()) {
Jorim Jaggi110839b2018-01-22 12:49:04 +0100650 setClientHidden(!visible);
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100651 }
652
lumark588a3e82018-07-20 18:53:54 +0800653 if (!getDisplayContent().mClosingApps.contains(this)
654 && !getDisplayContent().mOpeningApps.contains(this)) {
chaviwa953fcf2018-03-01 12:00:39 -0800655 // The token is not closing nor opening, so even if there is an animation set, that
656 // doesn't mean that it goes through the normal app transition cycle so we have
657 // to inform the docked controller about visibility change.
658 // TODO(multi-display): notify docked divider on all displays where visibility was
659 // affected.
lumark588a3e82018-07-20 18:53:54 +0800660 getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged();
chaviwa953fcf2018-03-01 12:00:39 -0800661
662 // Take the screenshot before possibly hiding the WSA, otherwise the screenshot
663 // will not be taken.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800664 mWmService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
chaviwa953fcf2018-03-01 12:00:39 -0800665 }
666
Robert Carre7cc44d2017-03-20 19:04:30 -0700667 // If we are hidden but there is no delay needed we immediately
668 // apply the Surface transaction so that the ActivityManager
Robert Carr61b81112017-07-17 18:08:15 -0700669 // can have some guarantee on the Surface state following
670 // setting the visibility. This captures cases like dismissing
671 // the docked or pinned stack where there is no app transition.
672 //
673 // In the case of a "Null" animation, there will be
674 // no animation but there will still be a transition set.
675 // We still need to delay hiding the surface such that it
676 // can be synchronized with showing the next surface in the transition.
lumark588a3e82018-07-20 18:53:54 +0800677 if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) {
Robert Carr6914f082017-03-20 19:04:30 -0700678 SurfaceControl.openTransaction();
679 for (int i = mChildren.size() - 1; i >= 0; i--) {
680 mChildren.get(i).mWinAnimator.hide("immediately hidden");
681 }
682 SurfaceControl.closeTransaction();
683 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700684 }
685
686 return delayed;
687 }
688
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200689 /**
690 * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns
691 * true.
692 */
693 WindowState getTopFullscreenWindow() {
694 for (int i = mChildren.size() - 1; i >= 0; i--) {
695 final WindowState win = mChildren.get(i);
696 if (win != null && win.mAttrs.isFullscreen()) {
697 return win;
698 }
699 }
700 return null;
701 }
702
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800703 WindowState findMainWindow() {
Matthew Ng53e66b22018-01-12 17:13:13 -0800704 return findMainWindow(true);
705 }
706
707 /**
708 * Finds the main window that either has type base application or application starting if
709 * requested.
710 *
711 * @param includeStartingApp Allow to search application-starting windows to also be returned.
712 * @return The main window of type base application or application starting if requested.
713 */
714 WindowState findMainWindow(boolean includeStartingApp) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700715 WindowState candidate = null;
Matthew Ng53e66b22018-01-12 17:13:13 -0800716 for (int j = mChildren.size() - 1; j >= 0; --j) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700717 final WindowState win = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700718 final int type = win.mAttrs.type;
719 // No need to loop through child window as base application and starting types can't be
720 // child windows.
Matthew Ng53e66b22018-01-12 17:13:13 -0800721 if (type == TYPE_BASE_APPLICATION
722 || (includeStartingApp && type == TYPE_APPLICATION_STARTING)) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700723 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900724 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700725 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800726 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700727 candidate = win;
728 } else {
729 return win;
730 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800731 }
732 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700733 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800734 }
735
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800736 boolean windowsAreFocusable() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800737 if (mTargetSdk < Build.VERSION_CODES.Q) {
738 final int pid = mActivityRecord != null
739 ? (mActivityRecord.app != null ? mActivityRecord.app.getPid() : 0) : 0;
740 final AppWindowToken topFocusedAppOfMyProcess =
741 mWmService.mRoot.mTopFocusedAppByProcess.get(pid);
742 if (topFocusedAppOfMyProcess != null && topFocusedAppOfMyProcess != this) {
743 // For the apps below Q, there can be only one app which has the focused window per
744 // process, because legacy apps may not be ready for a multi-focus system.
745 return false;
746 }
747 }
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700748 return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800749 }
750
Wale Ogunwale571771c2016-08-26 13:18:50 -0700751 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700752 boolean isVisible() {
Wale Ogunwalee471be62016-10-03 07:53:55 -0700753 // If the app token isn't hidden then it is considered visible and there is no need to check
754 // its children windows to see if they are visible.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200755 return !isHidden();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700756 }
757
758 @Override
Wale Ogunwalee287e192017-04-21 09:30:12 -0700759 void removeImmediately() {
760 onRemovedFromDisplay();
Yunfan Chen3a77f282018-12-12 15:47:52 -0800761 if (mActivityRecord != null) {
762 mActivityRecord.unregisterConfigurationChangeListener(this);
763 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700764 super.removeImmediately();
765 }
766
767 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700768 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800769 mIsExiting = false;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800770 removeAllWindowsIfPossible();
Bryce Lee6d410262017-02-28 15:30:17 -0800771 removeImmediately();
Craig Mautnere3119b72015-01-20 15:02:36 -0800772 }
773
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700774 @Override
775 boolean checkCompleteDeferredRemoval() {
776 if (mIsExiting) {
777 removeIfPossible();
778 }
779 return super.checkCompleteDeferredRemoval();
780 }
781
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700782 void onRemovedFromDisplay() {
Wale Ogunwalee287e192017-04-21 09:30:12 -0700783 if (mRemovingFromDisplay) {
784 return;
785 }
786 mRemovingFromDisplay = true;
787
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700788 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
789
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800790 boolean delayed = commitVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700791
lumark588a3e82018-07-20 18:53:54 +0800792 getDisplayContent().mOpeningApps.remove(this);
793 getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800794 mWmService.mTaskSnapshotController.onAppRemoved(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700795 waitingToShow = false;
lumark588a3e82018-07-20 18:53:54 +0800796 if (getDisplayContent().mClosingApps.contains(this)) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700797 delayed = true;
lumark588a3e82018-07-20 18:53:54 +0800798 } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
799 getDisplayContent().mClosingApps.add(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700800 delayed = true;
801 }
802
803 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200804 + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700805
806 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
807 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
808
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800809 if (startingData != null) {
810 removeStartingWindow();
Jorim Jaggi19be6052017-08-03 18:33:43 +0200811 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800812
Winson Chung87e5d552017-04-05 11:49:38 -0700813 // If this window was animating, then we need to ensure that the app transition notifies
lumark588a3e82018-07-20 18:53:54 +0800814 // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
815 // so add to that list now
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200816 if (isSelfAnimating()) {
lumark588a3e82018-07-20 18:53:54 +0800817 getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
Winson Chung87e5d552017-04-05 11:49:38 -0700818 }
819
Wale Ogunwalee287e192017-04-21 09:30:12 -0700820 final TaskStack stack = getStack();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700821 if (delayed && !isEmpty()) {
822 // set the token aside because it has an active animation to be finished
823 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
824 "removeAppToken make exiting: " + this);
Wale Ogunwalee287e192017-04-21 09:30:12 -0700825 if (stack != null) {
826 stack.mExitingAppTokens.add(this);
827 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700828 mIsExiting = true;
829 } else {
830 // Make sure there is no animation running on this token, so any windows associated
831 // with it will be removed as soon as their animations are complete
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200832 cancelAnimation();
Wale Ogunwale3106ae012017-05-16 08:56:37 -0700833 if (stack != null) {
834 stack.mExitingAppTokens.remove(this);
835 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700836 removeIfPossible();
837 }
838
839 removed = true;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700840 stopFreezingScreen(true, true);
Bryce Lee6d410262017-02-28 15:30:17 -0800841
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800842 final DisplayContent dc = getDisplayContent();
843 if (dc.mFocusedApp == this) {
844 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
845 + " displayId=" + dc.getDisplayId());
846 dc.setFocusedApp(null);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800847 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700848 }
849
850 if (!delayed) {
851 updateReportedVisibilityLocked();
852 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700853
854 mRemovingFromDisplay = false;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700855 }
856
Chong Zhange05bcb12016-07-26 17:47:29 -0700857 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700858 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700859 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700860 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700861 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700862 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700863 if (wallpaperMightChange) {
864 requestUpdateWallpaperIfNeeded();
865 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700866 }
867
Robert Carre12aece2016-02-02 22:43:27 -0800868 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700869 destroySurfaces(false /*cleanupOnResume*/);
870 }
871
872 /**
873 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
874 * the client has finished with them.
875 *
876 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
877 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
878 * others so that they are ready to be reused. If set to false (common case), destroy all
879 * surfaces that's eligible, if the app is already stopped.
880 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700881 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700882 boolean destroyedSomething = false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100883
884 // Copying to a different list as multiple children can be removed.
Jorim Jaggi59f3e922018-01-05 15:40:32 +0100885 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100886 for (int i = children.size() - 1; i >= 0; i--) {
887 final WindowState win = children.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700888 destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
Robert Carre12aece2016-02-02 22:43:27 -0800889 }
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700890 if (destroyedSomething) {
891 final DisplayContent dc = getDisplayContent();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700892 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Adrian Roos23df3a32018-03-15 15:41:13 +0100893 updateLetterboxSurface(null);
Robert Carre12aece2016-02-02 22:43:27 -0800894 }
895 }
896
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800897 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700898 * Notify that the app is now resumed, and it was not stopped before, perform a clean
899 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800900 */
Jorim Jaggibae01b12017-04-11 16:29:10 -0700901 void notifyAppResumed(boolean wasStopped) {
Chong Zhangad24f962016-08-25 12:12:33 -0700902 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
Jorim Jaggibae01b12017-04-11 16:29:10 -0700903 + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700904 mAppStopped = false;
chaviwd3bf08d2017-08-01 17:24:59 -0700905 // Allow the window to turn the screen on once the app is resumed again.
906 setCanTurnScreenOn(true);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700907 if (!wasStopped) {
908 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800909 }
Robert Carre12aece2016-02-02 22:43:27 -0800910 }
911
Chong Zhangbef461f2015-10-27 11:38:24 -0700912 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700913 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
914 * keeping alive in case they were still being used.
915 */
916 void notifyAppStopped() {
917 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
918 mAppStopped = true;
919 destroySurfaces();
920 // Remove any starting window that was added for this app if they are still around.
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800921 removeStartingWindow();
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700922 }
923
Chong Zhang92147042016-05-09 12:47:11 -0700924 void clearAllDrawn() {
925 allDrawn = false;
926 deferClearAllDrawn = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700927 }
928
Bryce Lee6d410262017-02-28 15:30:17 -0800929 Task getTask() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800930 return (Task) getParent();
Bryce Lee6d410262017-02-28 15:30:17 -0800931 }
932
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800933 TaskStack getStack() {
934 final Task task = getTask();
935 if (task != null) {
936 return task.mStack;
937 } else {
938 return null;
939 }
940 }
941
Bryce Lee6d410262017-02-28 15:30:17 -0800942 @Override
943 void onParentSet() {
944 super.onParentSet();
945
Robert Carred3e83b2017-04-21 13:26:55 -0700946 final Task task = getTask();
947
Bryce Lee6d410262017-02-28 15:30:17 -0800948 // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
949 // access visual elements like the {@link DisplayContent}. We must remove any associations
950 // such as animations.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800951 if (!mReparenting) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800952 if (task == null) {
953 // It is possible we have been marked as a closing app earlier. We must remove ourselves
954 // from this list so we do not participate in any future animations.
lumark588a3e82018-07-20 18:53:54 +0800955 getDisplayContent().mClosingApps.remove(this);
Robert Carred3e83b2017-04-21 13:26:55 -0700956 } else if (mLastParent != null && mLastParent.mStack != null) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800957 task.mStack.mExitingAppTokens.remove(this);
958 }
Bryce Lee6d410262017-02-28 15:30:17 -0800959 }
Jorim Jaggi6de61012018-03-19 14:53:23 +0100960 final TaskStack stack = getStack();
961
962 // If we reparent, make sure to remove ourselves from the old animation registry.
963 if (mAnimatingAppWindowTokenRegistry != null) {
964 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
965 }
966 mAnimatingAppWindowTokenRegistry = stack != null
967 ? stack.getAnimatingAppWindowTokenRegistry()
968 : null;
969
Robert Carred3e83b2017-04-21 13:26:55 -0700970 mLastParent = task;
Bryce Lee6d410262017-02-28 15:30:17 -0800971 }
972
Wale Ogunwalefa854eb2016-09-20 13:43:52 -0700973 void postWindowRemoveStartingWindowCleanup(WindowState win) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700974 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700975 if (startingWindow == win) {
976 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800977 removeStartingWindow();
Wale Ogunwale6c459212017-05-17 08:56:03 -0700978 } else if (mChildren.size() == 0) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700979 // If this is the last window and we had requested a starting transition window,
980 // well there is no point now.
Jorim Jaggi02886a82016-12-06 09:10:06 -0800981 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700982 startingData = null;
Wale Ogunwale6c459212017-05-17 08:56:03 -0700983 if (mHiddenSetFromTransferredStartingWindow) {
984 // We set the hidden state to false for the token from a transferred starting window.
985 // We now reset it back to true since the starting window was the last window in the
986 // token.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200987 setHidden(true);
Wale Ogunwale6c459212017-05-17 08:56:03 -0700988 }
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100989 } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700990 // If this is the last window except for a starting transition window,
991 // we need to get rid of the starting transition.
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200992 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
993 + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800994 removeStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700995 }
996 }
997
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700998 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700999 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001000 WindowState win = mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -08001001 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001002 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001003 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -08001004 // Set mDestroying, we don't want any animation or delayed removal here.
1005 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001006 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001007 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -08001008 }
1009 }
1010 }
1011
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001012 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001013 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001014 // No need to loop through child windows as the answer should be the same as that of the
1015 // parent window.
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001016 if (!(mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001017 return true;
1018 }
1019 }
1020 return false;
1021 }
1022
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001023 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001024 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1025 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -08001026
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001027 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001028 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001029 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -08001030 }
Robert Carra1eb4392015-12-10 12:43:51 -08001031 }
1032
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001033 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001034 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -08001035 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001036 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001037 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001038 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -08001039 }
1040 }
1041
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001042 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001043 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1044 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -08001045
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001046 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001047 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001048 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -08001049 }
1050 }
1051
Chong Zhang4d7369a2016-04-25 16:09:14 -07001052 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001053 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001054 final WindowState w = mChildren.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -07001055 w.requestUpdateWallpaperIfNeeded();
1056 }
1057 }
1058
Chong Zhangd78ddb42016-03-02 17:01:14 -08001059 boolean isRelaunching() {
1060 return mPendingRelaunchCount > 0;
1061 }
1062
Robert Carr68375192017-06-13 12:41:53 -07001063 boolean shouldFreezeBounds() {
1064 final Task task = getTask();
1065
1066 // For freeform windows, we can't freeze the bounds at the moment because this would make
1067 // the resizing unresponsive.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001068 if (task == null || task.inFreeformWindowingMode()) {
Robert Carr68375192017-06-13 12:41:53 -07001069 return false;
1070 }
1071
1072 // We freeze the bounds while drag resizing to deal with the time between
1073 // the divider/drag handle being released, and the handling it's new
1074 // configuration. If we are relaunched outside of the drag resizing state,
1075 // we need to be careful not to do this.
1076 return getTask().isDragResizing();
1077 }
1078
Chong Zhangd78ddb42016-03-02 17:01:14 -08001079 void startRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001080 if (shouldFreezeBounds()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001081 freezeBounds();
1082 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001083
1084 // In the process of tearing down before relaunching, the app will
1085 // try and clean up it's child surfaces. We need to prevent this from
1086 // happening, so we sever the children, transfering their ownership
1087 // from the client it-self to the parent surface (owned by us).
Robert Carr29daa922018-04-27 11:56:48 -07001088 detachChildren();
1089
1090 mPendingRelaunchCount++;
1091 }
1092
1093 void detachChildren() {
Robert Carrfd8e93b2018-05-10 13:40:25 -07001094 SurfaceControl.openTransaction();
Robert Carrd5c7dd62017-03-08 10:39:30 -08001095 for (int i = mChildren.size() - 1; i >= 0; i--) {
1096 final WindowState w = mChildren.get(i);
1097 w.mWinAnimator.detachChildren();
1098 }
Robert Carrfd8e93b2018-05-10 13:40:25 -07001099 SurfaceControl.closeTransaction();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001100 }
1101
1102 void finishRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001103 unfreezeBounds();
1104
Chong Zhangd78ddb42016-03-02 17:01:14 -08001105 if (mPendingRelaunchCount > 0) {
1106 mPendingRelaunchCount--;
Bryce Lee081554b2017-05-25 07:52:12 -07001107 } else {
1108 // Update keyguard flags upon finishing relaunch.
1109 checkKeyguardFlagsChanged();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001110 }
1111 }
1112
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001113 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001114 if (mPendingRelaunchCount == 0) {
1115 return;
1116 }
Robert Carr68375192017-06-13 12:41:53 -07001117 unfreezeBounds();
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001118 mPendingRelaunchCount = 0;
1119 }
1120
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001121 /**
1122 * Returns true if the new child window we are adding to this token is considered greater than
1123 * the existing child window in this token in terms of z-order.
1124 */
1125 @Override
1126 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
1127 WindowState existingWindow) {
1128 final int type1 = newWindow.mAttrs.type;
1129 final int type2 = existingWindow.mAttrs.type;
1130
1131 // Base application windows should be z-ordered BELOW all other windows in the app token.
1132 if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
1133 return false;
1134 } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
1135 return true;
1136 }
1137
1138 // Starting windows should be z-ordered ABOVE all other windows in the app token.
1139 if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
1140 return true;
1141 } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
1142 return false;
1143 }
1144
1145 // Otherwise the new window is greater than the existing window.
1146 return true;
1147 }
1148
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001149 @Override
Robert Carra1eb4392015-12-10 12:43:51 -08001150 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001151 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001152
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001153 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001154 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001155 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001156 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
1157 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001158
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001159 // if we got a replacement window, reset the timeout to give drawing more time
1160 if (gotReplacementWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001161 mWmService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -08001162 }
Jorim Jaggife762342016-10-13 14:33:27 +02001163 checkKeyguardFlagsChanged();
1164 }
1165
1166 @Override
1167 void removeChild(WindowState child) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001168 if (!mChildren.contains(child)) {
1169 // This can be true when testing.
1170 return;
1171 }
Jorim Jaggife762342016-10-13 14:33:27 +02001172 super.removeChild(child);
1173 checkKeyguardFlagsChanged();
Adrian Roos23df3a32018-03-15 15:41:13 +01001174 updateLetterboxSurface(child);
Robert Carra1eb4392015-12-10 12:43:51 -08001175 }
1176
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001177 private boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001178 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001179 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001180 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -08001181 return true;
1182 }
1183 }
1184 return false;
1185 }
1186
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001187 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001188 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001189 (mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -08001190 }
1191 }
1192
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001193 void reparent(Task task, int position) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001194 if (DEBUG_ADD_REMOVE) {
1195 Slog.i(TAG_WM, "reparent: moving app token=" + this
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001196 + " to task=" + task.mTaskId + " at " + position);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001197 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001198 if (task == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001199 throw new IllegalArgumentException("reparent: could not find task");
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001200 }
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001201 final Task currentTask = getTask();
1202 if (task == currentTask) {
Winson Chung30480042017-01-26 10:55:34 -08001203 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001204 "window token=" + this + " already child of task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001205 }
Bryce Lee6d410262017-02-28 15:30:17 -08001206
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001207 if (currentTask.mStack != task.mStack) {
Bryce Lee6d410262017-02-28 15:30:17 -08001208 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001209 "window token=" + this + " current task=" + currentTask
Bryce Lee6d410262017-02-28 15:30:17 -08001210 + " belongs to a different stack than " + task);
1211 }
1212
Winson Chung30480042017-01-26 10:55:34 -08001213 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001214 + " from task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001215 final DisplayContent prevDisplayContent = getDisplayContent();
1216
Bryce Lee6d410262017-02-28 15:30:17 -08001217 mReparenting = true;
1218
Winson Chung30480042017-01-26 10:55:34 -08001219 getParent().removeChild(this);
1220 task.addChild(this, position);
1221
Bryce Lee6d410262017-02-28 15:30:17 -08001222 mReparenting = false;
1223
Winson Chung30480042017-01-26 10:55:34 -08001224 // Relayout display(s).
1225 final DisplayContent displayContent = task.getDisplayContent();
1226 displayContent.setLayoutNeeded();
1227 if (prevDisplayContent != displayContent) {
1228 onDisplayChanged(displayContent);
1229 prevDisplayContent.setLayoutNeeded();
1230 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001231 getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
Winson Chung30480042017-01-26 10:55:34 -08001232 }
1233
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001234 @Override
1235 void onDisplayChanged(DisplayContent dc) {
1236 DisplayContent prevDc = mDisplayContent;
1237 super.onDisplayChanged(dc);
1238 if (prevDc != null && prevDc.mFocusedApp == this) {
1239 prevDc.setFocusedApp(null);
lumarkbf844642018-11-23 17:11:36 +08001240 final TaskStack stack = dc.getTopStack();
1241 if (stack != null) {
1242 final Task task = stack.getTopChild();
1243 if (task != null && task.getTopChild() == this) {
1244 dc.setFocusedApp(this);
1245 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001246 }
1247 }
1248 }
1249
Jorim Jaggi0429f352015-12-22 16:29:16 +01001250 /**
1251 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
1252 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
1253 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
1254 * with a queue.
1255 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001256 private void freezeBounds() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001257 final Task task = getTask();
1258 mFrozenBounds.offer(new Rect(task.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001259
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001260 if (task.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001261 // We didn't call prepareFreezingBounds on the task, so use the current value.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001262 mFrozenMergedConfig.offer(new Configuration(task.getConfiguration()));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001263 } else {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001264 mFrozenMergedConfig.offer(new Configuration(task.mPreparedFrozenMergedConfig));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001265 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001266 // Calling unset() to make it equal to Configuration.EMPTY.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001267 task.mPreparedFrozenMergedConfig.unset();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001268 }
1269
1270 /**
1271 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
1272 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001273 private void unfreezeBounds() {
Robert Carr68375192017-06-13 12:41:53 -07001274 if (mFrozenBounds.isEmpty()) {
1275 return;
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001276 }
Robert Carr68375192017-06-13 12:41:53 -07001277 mFrozenBounds.remove();
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001278 if (!mFrozenMergedConfig.isEmpty()) {
1279 mFrozenMergedConfig.remove();
1280 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001281 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001282 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001283 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +01001284 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001285 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001286 }
1287
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001288 void setAppLayoutChanges(int changes, String reason) {
1289 if (!mChildren.isEmpty()) {
1290 final DisplayContent dc = getDisplayContent();
1291 dc.pendingLayoutChanges |= changes;
1292 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001293 mWmService.mWindowPlacerLocked.debugLayoutRepeats(reason, dc.pendingLayoutChanges);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001294 }
1295 }
1296 }
1297
1298 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001299 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001300 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001301 if (win.removeReplacedWindowIfNeeded(replacement)) {
1302 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001303 }
1304 }
1305 }
1306
1307 void startFreezingScreen() {
1308 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001309 + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001310 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001311 if (!hiddenRequested) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001312 if (!mFreezingScreen) {
1313 mFreezingScreen = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001314 mWmService.registerAppFreezeListener(this);
1315 mWmService.mAppsFreezingScreen++;
1316 if (mWmService.mAppsFreezingScreen == 1) {
1317 mWmService.startFreezingDisplayLocked(0, 0, getDisplayContent());
1318 mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1319 mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001320 }
1321 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001322 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001323 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001324 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001325 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001326 }
1327 }
1328 }
1329
1330 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001331 if (!mFreezingScreen) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001332 return;
1333 }
1334 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001335 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001336 boolean unfrozeWindows = false;
1337 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001338 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001339 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001340 }
1341 if (force || unfrozeWindows) {
1342 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001343 mFreezingScreen = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001344 mWmService.unregisterAppFreezeListener(this);
1345 mWmService.mAppsFreezingScreen--;
1346 mWmService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001347 }
1348 if (unfreezeSurfaceNow) {
1349 if (unfrozeWindows) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001350 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001351 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001352 mWmService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001353 }
1354 }
1355
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001356 @Override
1357 public void onAppFreezeTimeout() {
1358 Slog.w(TAG_WM, "Force clearing freeze: " + this);
1359 stopFreezingScreen(true, true);
1360 }
1361
Jorim Jaggi60f9c972018-02-01 19:21:07 +01001362 /**
1363 * Tries to transfer the starting window from a token that's above ourselves in the task but
1364 * not visible anymore. This is a common scenario apps use: Trampoline activity T start main
1365 * activity M in the same task. Now, when reopening the task, T starts on top of M but then
1366 * immediately finishes after, so we have to transfer T to M.
1367 */
1368 void transferStartingWindowFromHiddenAboveTokenIfNeeded() {
1369 final Task task = getTask();
1370 for (int i = task.mChildren.size() - 1; i >= 0; i--) {
1371 final AppWindowToken fromToken = task.mChildren.get(i);
1372 if (fromToken == this) {
1373 return;
1374 }
1375 if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) {
1376 return;
1377 }
1378 }
1379 }
1380
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001381 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001382 final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001383 if (fromToken == null) {
1384 return false;
1385 }
1386
1387 final WindowState tStartingWindow = fromToken.startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001388 if (tStartingWindow != null && fromToken.startingSurface != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001389 // In this case, the starting icon has already been displayed, so start
1390 // letting windows get shown immediately without any more transitions.
lumark588a3e82018-07-20 18:53:54 +08001391 getDisplayContent().mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001392
1393 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1394 + " from " + fromToken + " to " + this);
1395
1396 final long origId = Binder.clearCallingIdentity();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001397 try {
1398 // Transfer the starting window over to the new token.
1399 startingData = fromToken.startingData;
1400 startingSurface = fromToken.startingSurface;
1401 startingDisplayed = fromToken.startingDisplayed;
1402 fromToken.startingDisplayed = false;
1403 startingWindow = tStartingWindow;
1404 reportedVisible = fromToken.reportedVisible;
1405 fromToken.startingData = null;
1406 fromToken.startingSurface = null;
1407 fromToken.startingWindow = null;
1408 fromToken.startingMoved = true;
1409 tStartingWindow.mToken = this;
1410 tStartingWindow.mAppToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001411
Peter Visontay3556a3b2017-11-01 17:23:17 +00001412 if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1413 "Removing starting " + tStartingWindow + " from " + fromToken);
1414 fromToken.removeChild(tStartingWindow);
1415 fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
1416 fromToken.mHiddenSetFromTransferredStartingWindow = false;
1417 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001418
Peter Visontay3556a3b2017-11-01 17:23:17 +00001419 // Propagate other interesting state between the tokens. If the old token is displayed,
1420 // we should immediately force the new one to be displayed. If it is animating, we need
1421 // to move that animation to the new one.
1422 if (fromToken.allDrawn) {
1423 allDrawn = true;
1424 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1425 }
1426 if (fromToken.firstWindowDrawn) {
1427 firstWindowDrawn = true;
1428 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001429 if (!fromToken.isHidden()) {
1430 setHidden(false);
Peter Visontay3556a3b2017-11-01 17:23:17 +00001431 hiddenRequested = false;
1432 mHiddenSetFromTransferredStartingWindow = true;
1433 }
1434 setClientHidden(fromToken.mClientHidden);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001435
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001436 transferAnimation(fromToken);
1437
1438 // When transferring an animation, we no longer need to apply an animation to the
1439 // the token we transfer the animation over. Thus, remove the animation from
1440 // pending opening apps.
lumark588a3e82018-07-20 18:53:54 +08001441 getDisplayContent().mOpeningApps.remove(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001442
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001443 mWmService.updateFocusedWindowLocked(
Peter Visontay3556a3b2017-11-01 17:23:17 +00001444 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
1445 getDisplayContent().setLayoutNeeded();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001446 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001447 } finally {
1448 Binder.restoreCallingIdentity(origId);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001449 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001450 return true;
1451 } else if (fromToken.startingData != null) {
1452 // The previous app was getting ready to show a
1453 // starting window, but hasn't yet done so. Steal it!
1454 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1455 "Moving pending starting from " + fromToken + " to " + this);
1456 startingData = fromToken.startingData;
1457 fromToken.startingData = null;
1458 fromToken.startingMoved = true;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001459 scheduleAddStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001460 return true;
1461 }
1462
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001463 // TODO: Transfer thumbnail
1464
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001465 return false;
1466 }
1467
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001468 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001469 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001470 }
1471
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001472 @Override
1473 void onAppTransitionDone() {
1474 sendingToBottom = false;
1475 }
1476
Wale Ogunwale51362492016-09-08 17:49:17 -07001477 /**
1478 * We override because this class doesn't want its children affecting its reported orientation
1479 * in anyway.
1480 */
1481 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001482 int getOrientation(int candidate) {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001483 if (candidate == SCREEN_ORIENTATION_BEHIND) {
1484 // Allow app to specify orientation regardless of its visibility state if the current
1485 // candidate want us to use orientation behind. I.e. the visible app on-top of this one
1486 // wants us to use the orientation of the app behind it.
1487 return mOrientation;
1488 }
1489
Bryce Lee61fbcbc2017-03-10 14:14:03 -08001490 // The {@link AppWindowToken} should only specify an orientation when it is not closing or
1491 // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
1492 // an Activity in another task being started in the wrong orientation during the transition.
lumark588a3e82018-07-20 18:53:54 +08001493 if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
1494 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
Bryce Leea163b762017-01-24 11:05:01 -08001495 return mOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07001496 }
Bryce Leea163b762017-01-24 11:05:01 -08001497
1498 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001499 }
1500
Wale Ogunwaleb198b742016-12-01 08:44:09 -08001501 /** Returns the app's preferred orientation regardless of its currently visibility state. */
1502 int getOrientationIgnoreVisibility() {
1503 return mOrientation;
1504 }
1505
Craig Mautnerdbb79912012-03-01 18:59:14 -08001506 @Override
Winson Chunge55c0192017-08-24 14:50:48 -07001507 public void onConfigurationChanged(Configuration newParentConfig) {
1508 final int prevWinMode = getWindowingMode();
1509 super.onConfigurationChanged(newParentConfig);
1510 final int winMode = getWindowingMode();
1511
1512 if (prevWinMode == winMode) {
1513 return;
1514 }
1515
1516 if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) {
1517 // Entering PiP from fullscreen, reset the snap fraction
1518 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
Winson Chung82267ce2018-04-06 16:38:26 -07001519 } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED
1520 && !isHidden()) {
Winson Chunge55c0192017-08-24 14:50:48 -07001521 // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
1522 // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
1523 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
1524 if (pinnedStack != null) {
Winson Chung8efa1652018-06-06 09:34:23 -07001525 final Rect stackBounds;
1526 if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
1527 // We are animating the bounds, use the pre-animation bounds to save the snap
1528 // fraction
1529 stackBounds = pinnedStack.mPreAnimationBounds;
1530 } else {
1531 // We skip the animation if the fullscreen configuration is not compatible, so
1532 // use the current bounds to calculate the saved snap fraction instead
1533 // (see PinnedActivityStack.skipResizeAnimation())
1534 stackBounds = mTmpRect;
1535 pinnedStack.getBounds(stackBounds);
1536 }
Winson Chunge55c0192017-08-24 14:50:48 -07001537 mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
Winson Chung8efa1652018-06-06 09:34:23 -07001538 stackBounds);
Winson Chunge55c0192017-08-24 14:50:48 -07001539 }
1540 }
1541 }
1542
1543 @Override
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001544 void checkAppWindowsReadyToShow() {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001545 if (allDrawn == mLastAllDrawn) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001546 return;
1547 }
1548
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001549 mLastAllDrawn = allDrawn;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001550 if (!allDrawn) {
1551 return;
1552 }
1553
1554 // The token has now changed state to having all windows shown... what to do, what to do?
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001555 if (mFreezingScreen) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001556 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001557 stopFreezingScreen(false, true);
1558 if (DEBUG_ORIENTATION) Slog.i(TAG,
1559 "Setting mOrientationChangeComplete=true because wtoken " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001560 + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001561 // This will set mOrientationChangeComplete and cause a pass through layout.
1562 setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001563 "checkAppWindowsReadyToShow: freezingScreen");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001564 } else {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001565 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001566
1567 // We can now show all of the drawn windows!
lumark588a3e82018-07-20 18:53:54 +08001568 if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001569 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001570 }
1571 }
1572 }
1573
Matthew Ng5d23afa2017-06-21 16:16:24 -07001574 /**
Bryce Leed390deb2017-06-22 13:14:28 -07001575 * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
1576 * child {@link WindowState}. A child is considered if it has been passed into
1577 * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
1578 * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
1579 * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
1580 *
1581 * @return {@code true} If all children have been considered, {@code false}.
1582 */
1583 private boolean allDrawnStatesConsidered() {
Bryce Lee6311c4b2017-07-06 14:09:29 -07001584 for (int i = mChildren.size() - 1; i >= 0; --i) {
1585 final WindowState child = mChildren.get(i);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001586 if (child.mightAffectAllDrawn() && !child.getDrawnStateEvaluated()) {
Bryce Leed390deb2017-06-22 13:14:28 -07001587 return false;
1588 }
1589 }
1590 return true;
1591 }
1592
1593 /**
Matthew Ng5d23afa2017-06-21 16:16:24 -07001594 * Determines if the token has finished drawing. This should only be called from
1595 * {@link DisplayContent#applySurfaceChangesTransaction}
1596 */
Matthew Ng498c71d2017-04-18 13:55:45 -07001597 void updateAllDrawn() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001598 if (!allDrawn) {
Matthew Ng498c71d2017-04-18 13:55:45 -07001599 // Number of drawn windows can be less when a window is being relaunched, wait for
Bryce Leed390deb2017-06-22 13:14:28 -07001600 // all windows to be launched and drawn for this token be considered all drawn.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001601 final int numInteresting = mNumInterestingWindows;
Bryce Leed390deb2017-06-22 13:14:28 -07001602
1603 // We must make sure that all present children have been considered (determined by
1604 // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
1605 // drawn.
1606 if (numInteresting > 0 && allDrawnStatesConsidered()
1607 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001608 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001609 + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001610 allDrawn = true;
1611 // Force an additional layout pass where
1612 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
Matthew Ng498c71d2017-04-18 13:55:45 -07001613 if (mDisplayContent != null) {
1614 mDisplayContent.setLayoutNeeded();
1615 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001616 mWmService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Robert Carrecc06b32017-04-18 14:25:10 -07001617
Winson Chunge7ba6862017-05-24 12:13:33 -07001618 // Notify the pinned stack upon all windows drawn. If there was an animation in
1619 // progress then this signal will resume that animation.
Wale Ogunwale61911492017-10-11 08:50:50 -07001620 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
Winson Chunge7ba6862017-05-24 12:13:33 -07001621 if (pinnedStack != null) {
1622 pinnedStack.onAllWindowsDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -07001623 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001624 }
1625 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001626 }
1627
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001628 boolean keyDispatchingTimedOut(String reason, int windowPid) {
1629 return mActivityRecord != null && mActivityRecord.keyDispatchingTimedOut(reason, windowPid);
1630 }
1631
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001632 /**
1633 * Updated this app token tracking states for interesting and drawn windows based on the window.
1634 *
1635 * @return Returns true if the input window is considered interesting and drawn while all the
1636 * windows in this app token where not considered drawn as of the last pass.
1637 */
1638 boolean updateDrawnWindowStates(WindowState w) {
Bryce Leed390deb2017-06-22 13:14:28 -07001639 w.setDrawnStateEvaluated(true /*evaluated*/);
1640
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001641 if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001642 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001643 + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001644 }
1645
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001646 if (allDrawn && !mFreezingScreen) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001647 return false;
1648 }
1649
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001650 if (mLastTransactionSequence != mWmService.mTransactionSequence) {
1651 mLastTransactionSequence = mWmService.mTransactionSequence;
Matthew Ng53e66b22018-01-12 17:13:13 -08001652 mNumDrawnWindows = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001653 startingDisplayed = false;
Matthew Ng53e66b22018-01-12 17:13:13 -08001654
1655 // There is the main base application window, even if it is exiting, wait for it
1656 mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001657 }
1658
1659 final WindowStateAnimator winAnimator = w.mWinAnimator;
1660
1661 boolean isInterestingAndDrawn = false;
1662
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001663 if (!allDrawn && w.mightAffectAllDrawn()) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001664 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1665 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001666 + ", isAnimationSet=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001667 if (!w.isDrawnLw()) {
1668 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
1669 + " pv=" + w.mPolicyVisibility
1670 + " mDrawState=" + winAnimator.drawStateToString()
1671 + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001672 + " a=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001673 }
1674 }
1675
1676 if (w != startingWindow) {
1677 if (w.isInteresting()) {
Matthew Ng53e66b22018-01-12 17:13:13 -08001678 // Add non-main window as interesting since the main app has already been added
1679 if (findMainWindow(false /* includeStartingApp */) != w) {
1680 mNumInterestingWindows++;
1681 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001682 if (w.isDrawnLw()) {
1683 mNumDrawnWindows++;
1684
1685 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
1686 + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001687 + " freezingScreen=" + mFreezingScreen
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001688 + " mAppFreezing=" + w.mAppFreezing);
1689
1690 isInterestingAndDrawn = true;
1691 }
1692 }
1693 } else if (w.isDrawnLw()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001694 if (mActivityRecord != null) {
1695 mActivityRecord.onStartingWindowDrawn(SystemClock.uptimeMillis());
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001696 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001697 startingDisplayed = true;
1698 }
1699 }
1700
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001701 return isInterestingAndDrawn;
1702 }
1703
Adrian Roos23df3a32018-03-15 15:41:13 +01001704 void layoutLetterbox(WindowState winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001705 final WindowState w = findMainWindow();
Adrian Roosf93b6d22018-03-21 13:48:26 +01001706 if (w == null || winHint != null && w != winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001707 return;
1708 }
Jorim Jaggia32da382018-03-28 18:01:22 +02001709 final boolean surfaceReady = w.isDrawnLw() // Regular case
Adrian Roosf93b6d22018-03-21 13:48:26 +01001710 || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
1711 || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
1712 final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001713 if (needsLetterbox) {
1714 if (mLetterbox == null) {
1715 mLetterbox = new Letterbox(() -> makeChildSurface(null));
1716 }
chaviw492139a2018-07-16 16:07:35 -07001717 mLetterbox.layout(getParent().getBounds(), w.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001718 } else if (mLetterbox != null) {
Adrian Roos23df3a32018-03-15 15:41:13 +01001719 mLetterbox.hide();
1720 }
1721 }
1722
1723 void updateLetterboxSurface(WindowState winHint) {
1724 final WindowState w = findMainWindow();
1725 if (w != winHint && winHint != null && w != null) {
1726 return;
1727 }
1728 layoutLetterbox(winHint);
1729 if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
1730 mLetterbox.applySurfaceChanges(mPendingTransaction);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001731 }
1732 }
1733
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001734 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001735 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001736 // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
1737 // before the non-exiting app tokens. So, we skip the exiting app tokens here.
1738 // TODO: Investigate if we need to continue to do this or if we can just process them
1739 // in-order.
1740 if (mIsExiting && !waitingForReplacement()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001741 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001742 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001743 return forAllWindowsUnchecked(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001744 }
1745
lumark588a3e82018-07-20 18:53:54 +08001746 @Override
1747 void forAllAppWindows(Consumer<AppWindowToken> callback) {
1748 callback.accept(this);
1749 }
1750
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001751 boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
1752 boolean traverseTopToBottom) {
1753 return super.forAllWindows(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001754 }
1755
1756 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001757 AppWindowToken asAppWindowToken() {
1758 // I am an app window token!
1759 return this;
1760 }
1761
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001762 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1763 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1764 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1765 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1766 // If the display is frozen, we won't do anything until the actual window is
1767 // displayed so there is no reason to put in the starting window.
1768 if (!okToDisplay()) {
1769 return false;
1770 }
1771
1772 if (startingData != null) {
1773 return false;
1774 }
1775
1776 final WindowState mainWin = findMainWindow();
1777 if (mainWin != null && mainWin.mWinAnimator.getShown()) {
1778 // App already has a visible window...why would you want a starting window?
1779 return false;
1780 }
1781
1782 final ActivityManager.TaskSnapshot snapshot =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001783 mWmService.mTaskSnapshotController.getSnapshot(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001784 getTask().mTaskId, getTask().mUserId,
1785 false /* restoreFromDisk */, false /* reducedResolution */);
1786 final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
1787 allowTaskSnapshot, activityCreated, fromRecents, snapshot);
1788
1789 if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
1790 return createSnapshot(snapshot);
1791 }
1792
1793 // If this is a translucent window, then don't show a starting window -- the current
1794 // effect (a full-screen opaque starting window that fades away to the real contents
1795 // when it is ready) does not work for this.
1796 if (DEBUG_STARTING_WINDOW) {
1797 Slog.v(TAG, "Checking theme of starting window: 0x" + Integer.toHexString(theme));
1798 }
1799 if (theme != 0) {
1800 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
1801 com.android.internal.R.styleable.Window,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001802 mWmService.mCurrentUserId);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001803 if (ent == null) {
1804 // Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
1805 // see that.
1806 return false;
1807 }
1808 final boolean windowIsTranslucent = ent.array.getBoolean(
1809 com.android.internal.R.styleable.Window_windowIsTranslucent, false);
1810 final boolean windowIsFloating = ent.array.getBoolean(
1811 com.android.internal.R.styleable.Window_windowIsFloating, false);
1812 final boolean windowShowWallpaper = ent.array.getBoolean(
1813 com.android.internal.R.styleable.Window_windowShowWallpaper, false);
1814 final boolean windowDisableStarting = ent.array.getBoolean(
1815 com.android.internal.R.styleable.Window_windowDisablePreview, false);
1816 if (DEBUG_STARTING_WINDOW) {
1817 Slog.v(TAG, "Translucent=" + windowIsTranslucent
1818 + " Floating=" + windowIsFloating
1819 + " ShowWallpaper=" + windowShowWallpaper);
1820 }
1821 if (windowIsTranslucent) {
1822 return false;
1823 }
1824 if (windowIsFloating || windowDisableStarting) {
1825 return false;
1826 }
1827 if (windowShowWallpaper) {
1828 if (getDisplayContent().mWallpaperController
1829 .getWallpaperTarget() == null) {
1830 // If this theme is requesting a wallpaper, and the wallpaper
1831 // is not currently visible, then this effectively serves as
1832 // an opaque window and our starting window transition animation
1833 // can still work. We just need to make sure the starting window
1834 // is also showing the wallpaper.
1835 windowFlags |= FLAG_SHOW_WALLPAPER;
1836 } else {
1837 return false;
1838 }
1839 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001840 }
Yunfan Chen8a8c0ed2018-12-18 16:46:32 -08001841
1842 if (transferStartingWindow(transferFrom)) {
1843 return true;
1844 }
1845
1846 // There is no existing starting window, and we don't want to create a splash screen, so
1847 // that's it!
1848 if (type != STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
1849 return false;
1850 }
1851
1852 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
1853 startingData = new SplashScreenStartingData(mWmService, pkg,
1854 theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
1855 getMergedOverrideConfiguration());
1856 scheduleAddStartingWindow();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001857 return true;
1858 }
1859
1860
1861 private boolean createSnapshot(ActivityManager.TaskSnapshot snapshot) {
1862 if (snapshot == null) {
1863 return false;
1864 }
1865
1866 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001867 startingData = new SnapshotStartingData(mWmService, snapshot);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001868 scheduleAddStartingWindow();
1869 return true;
1870 }
1871
1872 void scheduleAddStartingWindow() {
1873 // Note: we really want to do sendMessageAtFrontOfQueue() because we
1874 // want to process the message ASAP, before any other queued
1875 // messages.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001876 if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001877 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001878 mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001879 }
1880 }
1881
1882 private final Runnable mAddStartingWindow = new Runnable() {
1883
1884 @Override
1885 public void run() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001886 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001887 // There can only be one adding request, silly caller!
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001888 mWmService.mAnimationHandler.removeCallbacks(this);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001889 }
1890
1891 if (startingData == null) {
1892 // Animation has been canceled... do nothing.
1893 if (DEBUG_STARTING_WINDOW) {
1894 Slog.v(TAG, "startingData was nulled out before handling"
1895 + " mAddStartingWindow: " + AppWindowToken.this);
1896 }
1897 return;
1898 }
1899
1900 if (DEBUG_STARTING_WINDOW) {
1901 Slog.v(TAG, "Add starting " + this + ": startingData=" + startingData);
1902 }
1903
1904 WindowManagerPolicy.StartingSurface surface = null;
1905 try {
1906 surface = startingData.createStartingSurface(AppWindowToken.this);
1907 } catch (Exception e) {
1908 Slog.w(TAG, "Exception when adding starting window", e);
1909 }
1910 if (surface != null) {
1911 boolean abort = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001912 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001913 // If the window was successfully added, then
1914 // we need to remove it.
1915 if (removed || startingData == null) {
1916 if (DEBUG_STARTING_WINDOW) {
1917 Slog.v(TAG, "Aborted starting " + AppWindowToken.this
1918 + ": removed=" + removed + " startingData=" + startingData);
1919 }
1920 startingWindow = null;
1921 startingData = null;
1922 abort = true;
1923 } else {
1924 startingSurface = surface;
1925 }
1926 if (DEBUG_STARTING_WINDOW && !abort) {
1927 Slog.v(TAG, "Added starting " + AppWindowToken.this + ": startingWindow="
1928 + startingWindow + " startingView=" + startingSurface);
1929 }
1930 }
1931 if (abort) {
1932 surface.remove();
1933 }
1934 } else if (DEBUG_STARTING_WINDOW) {
1935 Slog.v(TAG, "Surface returned was null: " + AppWindowToken.this);
1936 }
1937 }
1938 };
1939
1940 private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
1941 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
1942 ActivityManager.TaskSnapshot snapshot) {
1943 if (getDisplayContent().mAppTransition.getAppTransition()
1944 == TRANSIT_DOCK_TASK_FROM_RECENTS) {
1945 // TODO(b/34099271): Remove this statement to add back the starting window and figure
1946 // out why it causes flickering, the starting window appears over the thumbnail while
1947 // the docked from recents transition occurs
1948 return STARTING_WINDOW_TYPE_NONE;
1949 } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
1950 return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1951 } else if (taskSwitch && allowTaskSnapshot) {
1952 return snapshot == null ? STARTING_WINDOW_TYPE_NONE
1953 : snapshotOrientationSameAsTask(snapshot) || fromRecents
1954 ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1955 } else {
1956 return STARTING_WINDOW_TYPE_NONE;
1957 }
1958 }
1959
1960
1961 private boolean snapshotOrientationSameAsTask(ActivityManager.TaskSnapshot snapshot) {
1962 if (snapshot == null) {
1963 return false;
1964 }
1965 return getTask().getConfiguration().orientation == snapshot.getOrientation();
1966 }
1967
1968 void removeStartingWindow() {
1969 if (startingWindow == null) {
1970 if (startingData != null) {
1971 // Starting window has not been added yet, but it is scheduled to be added.
1972 // Go ahead and cancel the request.
1973 if (DEBUG_STARTING_WINDOW) {
1974 Slog.v(TAG_WM, "Clearing startingData for token=" + this);
1975 }
1976 startingData = null;
1977 }
1978 return;
1979 }
1980
1981 final WindowManagerPolicy.StartingSurface surface;
1982 if (startingData != null) {
1983 surface = startingSurface;
1984 startingData = null;
1985 startingSurface = null;
1986 startingWindow = null;
1987 startingDisplayed = false;
1988 if (surface == null) {
1989 if (DEBUG_STARTING_WINDOW) {
1990 Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
1991 + "remove");
1992 }
1993 return;
1994 }
1995 } else {
1996 if (DEBUG_STARTING_WINDOW) {
1997 Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
1998 + this);
1999 }
2000 return;
2001 }
2002
2003 if (DEBUG_STARTING_WINDOW) {
2004 Slog.v(TAG_WM, "Schedule remove starting " + this
2005 + " startingWindow=" + startingWindow
2006 + " startingView=" + startingSurface
2007 + " Callers=" + Debug.getCallers(5));
2008 }
2009
2010 // Use the same thread to remove the window as we used to add it, as otherwise we end up
2011 // with things in the view hierarchy being called from different threads.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002012 mWmService.mAnimationHandler.post(() -> {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002013 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
2014 try {
2015 surface.remove();
2016 } catch (Exception e) {
2017 Slog.w(TAG_WM, "Exception when removing starting window", e);
2018 }
2019 });
2020 }
2021
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07002022 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07002023 boolean fillsParent() {
2024 return mFillsParent;
2025 }
2026
2027 void setFillsParent(boolean fillsParent) {
2028 mFillsParent = fillsParent;
2029 }
2030
Jorim Jaggife762342016-10-13 14:33:27 +02002031 boolean containsDismissKeyguardWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002032 // Window state is transient during relaunch. We are not guaranteed to be frozen during the
2033 // entirety of the relaunch.
2034 if (isRelaunching()) {
2035 return mLastContainsDismissKeyguardWindow;
2036 }
2037
Jorim Jaggife762342016-10-13 14:33:27 +02002038 for (int i = mChildren.size() - 1; i >= 0; i--) {
2039 if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
2040 return true;
2041 }
2042 }
2043 return false;
2044 }
2045
2046 boolean containsShowWhenLockedWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002047 // When we are relaunching, it is possible for us to be unfrozen before our previous
2048 // windows have been added back. Using the cached value ensures that our previous
2049 // showWhenLocked preference is honored until relaunching is complete.
2050 if (isRelaunching()) {
2051 return mLastContainsShowWhenLockedWindow;
2052 }
2053
Jorim Jaggife762342016-10-13 14:33:27 +02002054 for (int i = mChildren.size() - 1; i >= 0; i--) {
2055 if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
2056 return true;
2057 }
2058 }
Bryce Lee081554b2017-05-25 07:52:12 -07002059
Jorim Jaggife762342016-10-13 14:33:27 +02002060 return false;
2061 }
2062
2063 void checkKeyguardFlagsChanged() {
2064 final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
2065 final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
2066 if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
2067 || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002068 mWmService.notifyKeyguardFlagsChanged(null /* callback */,
lumark588a3e82018-07-20 18:53:54 +08002069 getDisplayContent().getDisplayId());
Jorim Jaggife762342016-10-13 14:33:27 +02002070 }
2071 mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
2072 mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
2073 }
2074
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002075 WindowState getImeTargetBelowWindow(WindowState w) {
2076 final int index = mChildren.indexOf(w);
2077 if (index > 0) {
2078 final WindowState target = mChildren.get(index - 1);
2079 if (target.canBeImeTarget()) {
2080 return target;
2081 }
2082 }
2083 return null;
2084 }
2085
2086 WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
2087 WindowState candidate = null;
2088 for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
2089 final WindowState w = mChildren.get(i);
2090 if (w.mRemoved) {
2091 continue;
2092 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02002093 if (candidate == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002094 candidate = w;
2095 }
2096 }
2097 return candidate;
2098 }
2099
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002100 /**
2101 * See {@link Activity#setDisablePreviewScreenshots}.
2102 */
2103 void setDisablePreviewScreenshots(boolean disable) {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002104 mDisablePreviewScreenshots = disable;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002105 }
2106
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002107 /**
chaviwd3bf08d2017-08-01 17:24:59 -07002108 * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
2109 */
2110 void setCanTurnScreenOn(boolean canTurnScreenOn) {
2111 mCanTurnScreenOn = canTurnScreenOn;
2112 }
2113
2114 /**
2115 * Indicates whether the current launch can turn the screen on. This is to prevent multiple
2116 * relayouts from turning the screen back on. The screen should only turn on at most
2117 * once per activity resume.
2118 *
2119 * @return true if the screen can be turned on.
2120 */
2121 boolean canTurnScreenOn() {
2122 return mCanTurnScreenOn;
2123 }
2124
2125 /**
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002126 * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
2127 * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
2128 * we can't take a snapshot for other reasons, for example, if we have a secure window.
2129 *
2130 * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
2131 * screenshot.
2132 */
2133 boolean shouldUseAppThemeSnapshot() {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002134 return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002135 true /* topToBottom */);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002136 }
2137
Jorim Jaggibe418292018-03-26 16:14:12 +02002138 SurfaceControl getAppAnimationLayer() {
Jorim Jaggi391790622018-04-18 15:30:44 +02002139 return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
2140 : needsZBoost() ? ANIMATION_LAYER_BOOSTED
2141 : ANIMATION_LAYER_STANDARD);
Jorim Jaggibe418292018-03-26 16:14:12 +02002142 }
2143
chaviw23ee71c2017-12-18 11:29:41 -08002144 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +01002145 public SurfaceControl getAnimationLeashParent() {
Robert Carrb9506032018-02-13 13:54:00 -08002146 // All normal app transitions take place in an animation layer which is below the pinned
2147 // stack but may be above the parent stacks of the given animating apps.
2148 // For transitions in the pinned stack (menu activity) we just let them occur as a child
2149 // of the pinned stack.
2150 if (!inPinnedWindowingMode()) {
2151 return getAppAnimationLayer();
2152 } else {
2153 return getStack().getSurfaceControl();
2154 }
chaviw23ee71c2017-12-18 11:29:41 -08002155 }
2156
Jorim Jaggic6976f02018-04-18 16:31:07 +02002157 private boolean shouldAnimate(int transit) {
2158 final boolean isSplitScreenPrimary =
2159 getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
2160 final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
2161
2162 // We animate always if it's not split screen primary, and only some special cases in split
2163 // screen primary because it causes issues with stack clipping when we run an un-minimize
2164 // animation at the same time.
2165 return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
2166 }
2167
Vishnu Naira2977262018-07-26 13:31:26 -07002168 /**
2169 * Creates a layer to apply crop to an animation.
2170 */
2171 private SurfaceControl createAnimationBoundsLayer(Transaction t) {
2172 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
2173 final SurfaceControl.Builder builder = makeAnimationLeash()
2174 .setParent(getAnimationLeashParent())
Vishnu Naire86bd982018-11-28 13:23:17 -08002175 .setName(getSurfaceControl() + " - animation-bounds");
Vishnu Naira2977262018-07-26 13:31:26 -07002176 final SurfaceControl boundsLayer = builder.build();
2177 t.show(boundsLayer);
2178 return boundsLayer;
2179 }
2180
Riddle Hsua118b3a2018-10-11 22:05:06 +08002181 /** Get position and crop region of animation. */
2182 @VisibleForTesting
2183 void getAnimationBounds(Point outPosition, Rect outBounds) {
2184 outPosition.set(0, 0);
2185 outBounds.setEmpty();
2186
2187 final TaskStack stack = getStack();
2188 final Task task = getTask();
2189 if (task != null && task.inFreeformWindowingMode()) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002190 task.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002191 } else if (stack != null) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002192 stack.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002193 }
2194
2195 // Always use stack bounds in order to have the ability to animate outside the task region.
2196 // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
2197 // according to the bounds.
2198 if (stack != null) {
2199 stack.getBounds(outBounds);
2200 }
2201 // We have the relative position so the local position can be removed from bounds.
2202 outBounds.offsetTo(0, 0);
2203 }
2204
Evan Roskyed6767f2018-10-26 17:21:06 -07002205 @Override
2206 Rect getDisplayedBounds() {
2207 final Task task = getTask();
2208 if (task != null) {
2209 final Rect overrideDisplayedBounds = task.getOverrideDisplayedBounds();
2210 if (!overrideDisplayedBounds.isEmpty()) {
2211 return overrideDisplayedBounds;
2212 }
2213 }
2214 return getBounds();
2215 }
2216
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002217 boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
2218 boolean isVoiceInteraction) {
2219
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002220 if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002221 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Jorim Jaggic6976f02018-04-18 16:31:07 +02002222 Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
2223 + " atoken=" + this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002224 }
2225 cancelAnimation();
2226 return false;
2227 }
2228
2229 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
2230 // to animate and it can cause strange artifacts when we unfreeze the display if some
2231 // different animation is running.
2232 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
2233 if (okToAnimate()) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002234 final AnimationAdapter adapter;
Riddle Hsua118b3a2018-10-11 22:05:06 +08002235 getAnimationBounds(mTmpPoint, mTmpRect);
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002236
2237 // Delaying animation start isn't compatible with remote animations at all.
lumark588a3e82018-07-20 18:53:54 +08002238 if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002239 && !mSurfaceAnimator.isAnimationStartDelayed()) {
lumark588a3e82018-07-20 18:53:54 +08002240 adapter = getDisplayContent().mAppTransition.getRemoteAnimationController()
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002241 .createAnimationAdapter(this, mTmpPoint, mTmpRect);
2242 } else {
lumark588a3e82018-07-20 18:53:54 +08002243 final int appStackClipMode =
2244 getDisplayContent().mAppTransition.getAppStackClipMode();
Vishnu Naira2977262018-07-26 13:31:26 -07002245 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
2246
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002247 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
2248 if (a != null) {
2249 adapter = new LocalAnimationAdapter(
2250 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
lumark588a3e82018-07-20 18:53:54 +08002251 getDisplayContent().mAppTransition.canSkipFirstFrame(),
Vishnu Naira2977262018-07-26 13:31:26 -07002252 appStackClipMode,
Jorim Jaggiaa763cd2018-03-22 23:20:36 +01002253 true /* isAppAnimation */),
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002254 mWmService.mSurfaceAnimationRunner);
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002255 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
2256 mNeedsZBoost = true;
2257 }
2258 mTransit = transit;
lumark588a3e82018-07-20 18:53:54 +08002259 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002260 } else {
2261 adapter = null;
chaviw23ee71c2017-12-18 11:29:41 -08002262 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002263 }
2264 if (adapter != null) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002265 startAnimation(getPendingTransaction(), adapter, !isVisible());
Jorim Jaggi82c17862018-02-21 17:50:18 +01002266 if (adapter.getShowWallpaper()) {
2267 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2268 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002269 }
2270 } else {
2271 cancelAnimation();
2272 }
2273 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2274
2275 return isReallyAnimating();
2276 }
2277
2278 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
2279 boolean isVoiceInteraction) {
2280 final DisplayContent displayContent = getTask().getDisplayContent();
2281 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2282 final int width = displayInfo.appWidth;
2283 final int height = displayInfo.appHeight;
2284 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
2285 "applyAnimation: atoken=" + this);
2286
2287 // Determine the visible rect to calculate the thumbnail clip
2288 final WindowState win = findMainWindow();
2289 final Rect frame = new Rect(0, 0, width, height);
2290 final Rect displayFrame = new Rect(0, 0,
2291 displayInfo.logicalWidth, displayInfo.logicalHeight);
2292 final Rect insets = new Rect();
2293 final Rect stableInsets = new Rect();
2294 Rect surfaceInsets = null;
2295 final boolean freeform = win != null && win.inFreeformWindowingMode();
2296 if (win != null) {
2297 // Containing frame will usually cover the whole screen, including dialog windows.
2298 // For freeform workspace windows it will not cover the whole screen and it also
2299 // won't exactly match the final freeform window frame (e.g. when overlapping with
2300 // the status bar). In that case we need to use the final frame.
2301 if (freeform) {
chaviw492139a2018-07-16 16:07:35 -07002302 frame.set(win.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01002303 } else if (win.isLetterboxedAppWindow()) {
2304 frame.set(getTask().getBounds());
Winson Chungc1674272018-02-21 10:15:17 -08002305 } else if (win.isDockedResizing()) {
2306 // If we are animating while docked resizing, then use the stack bounds as the
2307 // animation target (which will be different than the task bounds)
2308 frame.set(getTask().getParent().getBounds());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002309 } else {
chaviw553b0212018-07-12 13:37:01 -07002310 frame.set(win.getContainingFrame());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002311 }
2312 surfaceInsets = win.getAttrs().surfaceInsets;
Adrian Roos20e07892018-02-23 19:12:01 +01002313 // XXX(b/72757033): These are insets relative to the window frame, but we're really
2314 // interested in the insets relative to the frame we chose in the if-blocks above.
chaviw9c81e632018-07-31 11:17:52 -07002315 win.getContentInsets(insets);
2316 win.getStableInsets(stableInsets);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002317 }
2318
2319 if (mLaunchTaskBehind) {
2320 // Differentiate the two animations. This one which is briefly on the screen
2321 // gets the !enter animation, and the other activity which remains on the
2322 // screen gets the enter animation. Both appear in the mOpeningApps set.
2323 enter = false;
2324 }
2325 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
2326 + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
2327 + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
2328 final Configuration displayConfig = displayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002329 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002330 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
2331 surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
2332 if (a != null) {
2333 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
2334 final int containingWidth = frame.width();
2335 final int containingHeight = frame.height();
2336 a.initialize(containingWidth, containingHeight, width, height);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002337 a.scaleCurrentDuration(mWmService.getTransitionAnimationScaleLocked());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002338 }
2339 return a;
2340 }
2341
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002342 @Override
Jorim Jaggi6de61012018-03-19 14:53:23 +01002343 public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
2344 return mAnimatingAppWindowTokenRegistry != null
2345 && mAnimatingAppWindowTokenRegistry.notifyAboutToFinish(
2346 this, endDeferFinishCallback);
2347 }
2348
2349 @Override
2350 public void onAnimationLeashDestroyed(Transaction t) {
2351 super.onAnimationLeashDestroyed(t);
Vishnu Naira2977262018-07-26 13:31:26 -07002352 if (mAnimationBoundsLayer != null) {
2353 t.destroy(mAnimationBoundsLayer);
2354 mAnimationBoundsLayer = null;
2355 }
2356
Jorim Jaggi6de61012018-03-19 14:53:23 +01002357 if (mAnimatingAppWindowTokenRegistry != null) {
2358 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
2359 }
2360 }
2361
2362 @Override
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002363 protected void setLayer(Transaction t, int layer) {
2364 if (!mSurfaceAnimator.hasLeash()) {
2365 t.setLayer(mSurfaceControl, layer);
2366 }
2367 }
2368
2369 @Override
2370 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
2371 if (!mSurfaceAnimator.hasLeash()) {
2372 t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
2373 }
2374 }
2375
2376 @Override
2377 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
2378 if (!mSurfaceAnimator.hasLeash()) {
2379 t.reparent(mSurfaceControl, newParent.getHandle());
2380 }
2381 }
2382
2383 @Override
2384 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002385 // The leash is parented to the animation layer. We need to preserve the z-order by using
2386 // the prefix order index, but we boost if necessary.
Robert Carrb9506032018-02-13 13:54:00 -08002387 int layer = 0;
2388 if (!inPinnedWindowingMode()) {
2389 layer = getPrefixOrderIndex();
2390 } else {
2391 // Pinned stacks have animations take place within themselves rather than an animation
2392 // layer so we need to preserve the order relative to the stack (e.g. the order of our
2393 // task/parent).
2394 layer = getParent().getPrefixOrderIndex();
2395 }
2396
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002397 if (mNeedsZBoost) {
2398 layer += Z_BOOST_BASE;
2399 }
2400 leash.setLayer(layer);
Robert Carr2f8aa392018-01-31 14:46:51 -08002401
2402 final DisplayContent dc = getDisplayContent();
Jorim Jaggibe418292018-03-26 16:14:12 +02002403 dc.assignStackOrdering();
Jorim Jaggi6de61012018-03-19 14:53:23 +01002404 if (mAnimatingAppWindowTokenRegistry != null) {
2405 mAnimatingAppWindowTokenRegistry.notifyStarting(this);
2406 }
Vishnu Naira2977262018-07-26 13:31:26 -07002407
2408 // If the animation needs to be cropped then an animation bounds layer is created as a child
2409 // of the pinned stack or animation layer. The leash is then reparented to this new layer.
2410 if (mNeedsAnimationBoundsLayer) {
2411 final TaskStack stack = getStack();
2412 if (stack == null) {
2413 return;
2414 }
2415 mAnimationBoundsLayer = createAnimationBoundsLayer(t);
2416
2417 // Set clip rect to stack bounds.
2418 mTmpRect.setEmpty();
2419 stack.getBounds(mTmpRect);
2420
2421 // Crop to stack bounds.
2422 t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
2423
2424 // Reparent leash to animation bounds layer.
2425 t.reparent(leash, mAnimationBoundsLayer.getHandle());
2426 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002427 }
2428
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002429 /**
2430 * This must be called while inside a transaction.
2431 */
2432 void showAllWindowsLocked() {
2433 forAllWindows(windowState -> {
2434 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + windowState);
2435 windowState.performShowLocked();
2436 }, false /* traverseTopToBottom */);
Jorim Jaggia5e10572017-11-15 14:36:26 +01002437 }
2438
2439 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002440 protected void onAnimationFinished() {
2441 super.onAnimationFinished();
2442
2443 mTransit = TRANSIT_UNSET;
2444 mTransitFlags = 0;
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002445 mNeedsZBoost = false;
Vishnu Naira2977262018-07-26 13:31:26 -07002446 mNeedsAnimationBoundsLayer = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002447
2448 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
2449 "AppWindowToken");
2450
Jorim Jaggi988f6682017-11-17 17:46:43 +01002451 clearThumbnail();
Jorim Jaggi752cd822018-03-29 16:29:18 +02002452 setClientHidden(isHidden() && hiddenRequested);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002453
lumarkff0ab692018-11-05 20:32:30 +08002454 getDisplayContent().computeImeTargetIfNeeded(this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002455
2456 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this
2457 + ": reportedVisible=" + reportedVisible
2458 + " okToDisplay=" + okToDisplay()
2459 + " okToAnimate=" + okToAnimate()
2460 + " startingDisplayed=" + startingDisplayed);
2461
2462 // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
2463 // traverse the copy.
2464 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
2465 children.forEach(WindowState::onExitAnimationDone);
2466
lumark588a3e82018-07-20 18:53:54 +08002467 getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002468 scheduleAnimation();
2469 }
2470
2471 @Override
2472 boolean isAppAnimating() {
2473 return isSelfAnimating();
2474 }
2475
2476 @Override
2477 boolean isSelfAnimating() {
2478 // If we are about to start a transition, we also need to be considered animating.
2479 return isWaitingForTransitionStart() || isReallyAnimating();
2480 }
2481
2482 /**
2483 * @return True if and only if we are actually running an animation. Note that
2484 * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
2485 * start.
2486 */
2487 private boolean isReallyAnimating() {
2488 return super.isSelfAnimating();
2489 }
2490
Jorim Jaggi988f6682017-11-17 17:46:43 +01002491 @Override
2492 void cancelAnimation() {
2493 super.cancelAnimation();
2494 clearThumbnail();
2495 }
2496
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002497 boolean isWaitingForTransitionStart() {
lumark588a3e82018-07-20 18:53:54 +08002498 return getDisplayContent().mAppTransition.isTransitionSet()
2499 && (getDisplayContent().mOpeningApps.contains(this)
2500 || getDisplayContent().mClosingApps.contains(this));
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002501 }
2502
2503 public int getTransit() {
2504 return mTransit;
2505 }
2506
2507 int getTransitFlags() {
2508 return mTransitFlags;
2509 }
2510
Jorim Jaggi988f6682017-11-17 17:46:43 +01002511 void attachThumbnailAnimation() {
2512 if (!isReallyAnimating()) {
2513 return;
2514 }
2515 final int taskId = getTask().mTaskId;
2516 final GraphicBuffer thumbnailHeader =
lumark588a3e82018-07-20 18:53:54 +08002517 getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002518 if (thumbnailHeader == null) {
2519 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
2520 return;
2521 }
2522 clearThumbnail();
2523 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
2524 mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
2525 }
2526
Tony Mak64b8d562017-12-28 17:44:02 +00002527 /**
2528 * Attaches a surface with a thumbnail for the
2529 * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
2530 */
2531 void attachCrossProfileAppsThumbnailAnimation() {
2532 if (!isReallyAnimating()) {
2533 return;
2534 }
2535 clearThumbnail();
2536
2537 final WindowState win = findMainWindow();
2538 if (win == null) {
2539 return;
2540 }
chaviw492139a2018-07-16 16:07:35 -07002541 final Rect frame = win.getFrameLw();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002542 final int thumbnailDrawableRes = getTask().mUserId == mWmService.mCurrentUserId
Tony Mak64b8d562017-12-28 17:44:02 +00002543 ? R.drawable.ic_account_circle
Tony Makda4af232018-04-27 11:01:10 +01002544 : R.drawable.ic_corp_badge;
Tony Mak64b8d562017-12-28 17:44:02 +00002545 final GraphicBuffer thumbnail =
lumark588a3e82018-07-20 18:53:54 +08002546 getDisplayContent().mAppTransition
Tony Mak64b8d562017-12-28 17:44:02 +00002547 .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
2548 if (thumbnail == null) {
2549 return;
2550 }
2551 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
2552 final Animation animation =
lumark588a3e82018-07-20 18:53:54 +08002553 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
chaviw492139a2018-07-16 16:07:35 -07002554 win.getFrameLw());
Tony Mak64b8d562017-12-28 17:44:02 +00002555 mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
2556 frame.top));
2557 }
2558
Jorim Jaggi988f6682017-11-17 17:46:43 +01002559 private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
2560 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
2561
2562 // If this is a multi-window scenario, we use the windows frame as
2563 // destination of the thumbnail header animation. If this is a full screen
2564 // window scenario, we use the whole display as the target.
2565 WindowState win = findMainWindow();
2566 Rect appRect = win != null ? win.getContentFrameLw() :
2567 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
chaviw9c81e632018-07-31 11:17:52 -07002568 final Rect insets = win != null ? win.getContentInsets() : null;
Jorim Jaggi988f6682017-11-17 17:46:43 +01002569 final Configuration displayConfig = mDisplayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002570 return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
Jorim Jaggi988f6682017-11-17 17:46:43 +01002571 appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
2572 displayConfig.orientation);
2573 }
2574
2575 private void clearThumbnail() {
2576 if (mThumbnail == null) {
2577 return;
2578 }
2579 mThumbnail.destroy();
2580 mThumbnail = null;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002581 }
2582
Jorim Jaggif84e2f62018-01-16 14:17:59 +01002583 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
2584 mRemoteAnimationDefinition = definition;
2585 }
2586
2587 RemoteAnimationDefinition getRemoteAnimationDefinition() {
2588 return mRemoteAnimationDefinition;
2589 }
2590
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002591 @Override
2592 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2593 super.dump(pw, prefix, dumpAll);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002594 if (appToken != null) {
Wale Ogunwale72919d22016-12-08 18:58:50 -08002595 pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002596 }
Winson Chung48b25652018-10-22 14:04:30 -07002597 pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08002598 pw.print(prefix); pw.print("task="); pw.println(getTask());
Wale Ogunwale51362492016-09-08 17:49:17 -07002599 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
2600 pw.print(" mOrientation="); pw.println(mOrientation);
Wale Ogunwale89973222017-04-23 18:39:45 -07002601 pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
2602 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
2603 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07002604 if (paused) {
2605 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002606 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08002607 if (mAppStopped) {
2608 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
2609 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002610 if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002611 || allDrawn || mLastAllDrawn) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002612 pw.print(prefix); pw.print("mNumInterestingWindows=");
2613 pw.print(mNumInterestingWindows);
2614 pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002615 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07002616 pw.print(" allDrawn="); pw.print(allDrawn);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002617 pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
Craig Mautner6fbda632012-07-03 09:26:39 -07002618 pw.println(")");
2619 }
2620 if (inPendingTransaction) {
2621 pw.print(prefix); pw.print("inPendingTransaction=");
2622 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002623 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08002624 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002625 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
2626 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08002627 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08002628 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002629 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002630 if (startingWindow != null || startingSurface != null
Wale Ogunwale6c459212017-05-17 08:56:03 -07002631 || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002632 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002633 pw.print(" startingSurface="); pw.print(startingSurface);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002634 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale6c459212017-05-17 08:56:03 -07002635 pw.print(" startingMoved="); pw.print(startingMoved);
2636 pw.println(" mHiddenSetFromTransferredStartingWindow="
2637 + mHiddenSetFromTransferredStartingWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002638 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01002639 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08002640 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002641 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08002642 }
2643 if (mPendingRelaunchCount != 0) {
2644 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01002645 }
Wale Ogunwalee287e192017-04-21 09:30:12 -07002646 if (mRemovingFromDisplay) {
2647 pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
2648 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002649 }
2650
2651 @Override
2652 void setHidden(boolean hidden) {
2653 super.setHidden(hidden);
Winson Chunge55c0192017-08-24 14:50:48 -07002654
2655 if (hidden) {
2656 // Once the app window is hidden, reset the last saved PiP snap fraction
2657 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
2658 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002659 scheduleAnimation();
2660 }
2661
2662 @Override
2663 void prepareSurfaces() {
2664 // isSelfAnimating also returns true when we are about to start a transition, so we need
2665 // to check super here.
2666 final boolean reallyAnimating = super.isSelfAnimating();
2667 final boolean show = !isHidden() || reallyAnimating;
2668 if (show && !mLastSurfaceShowing) {
2669 mPendingTransaction.show(mSurfaceControl);
2670 } else if (!show && mLastSurfaceShowing) {
2671 mPendingTransaction.hide(mSurfaceControl);
Jorim Jaggi4d1835d2017-08-31 17:28:27 +02002672 }
Jorim Jaggi988f6682017-11-17 17:46:43 +01002673 if (mThumbnail != null) {
2674 mThumbnail.setShowing(mPendingTransaction, show);
2675 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002676 mLastSurfaceShowing = show;
2677 super.prepareSurfaces();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002678 }
2679
Jorim Jaggi77d0f36c2018-03-16 17:49:49 +01002680 /**
2681 * @return Whether our {@link #getSurfaceControl} is currently showing.
2682 */
2683 boolean isSurfaceShowing() {
2684 return mLastSurfaceShowing;
2685 }
2686
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002687 boolean isFreezingScreen() {
2688 return mFreezingScreen;
2689 }
2690
2691 @Override
2692 boolean needsZBoost() {
2693 return mNeedsZBoost || super.needsZBoost();
2694 }
2695
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07002696 @CallSuper
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002697 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02002698 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07002699 final long token = proto.start(fieldId);
2700 writeNameToProto(proto, NAME);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002701 super.writeToProto(proto, WINDOW_TOKEN, trim);
Vishnu Nair04ab4392018-01-10 11:00:06 -08002702 proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
2703 proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
2704 proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
2705 if (mThumbnail != null){
2706 mThumbnail.writeToProto(proto, THUMBNAIL);
2707 }
2708 proto.write(FILLS_PARENT, mFillsParent);
2709 proto.write(APP_STOPPED, mAppStopped);
2710 proto.write(HIDDEN_REQUESTED, hiddenRequested);
2711 proto.write(CLIENT_HIDDEN, mClientHidden);
2712 proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
2713 proto.write(REPORTED_DRAWN, reportedDrawn);
2714 proto.write(REPORTED_VISIBLE, reportedVisible);
2715 proto.write(NUM_INTERESTING_WINDOWS, mNumInterestingWindows);
2716 proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
2717 proto.write(ALL_DRAWN, allDrawn);
2718 proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
2719 proto.write(REMOVED, removed);
2720 if (startingWindow != null){
2721 startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
2722 }
2723 proto.write(STARTING_DISPLAYED, startingDisplayed);
2724 proto.write(STARTING_MOVED, startingMoved);
2725 proto.write(HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW,
2726 mHiddenSetFromTransferredStartingWindow);
2727 for (Rect bounds : mFrozenBounds) {
2728 bounds.writeToProto(proto, FROZEN_BOUNDS);
2729 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002730 proto.end(token);
2731 }
2732
2733 void writeNameToProto(ProtoOutputStream proto, long fieldId) {
2734 if (appToken == null) {
2735 return;
2736 }
2737 try {
2738 proto.write(fieldId, appToken.getName());
2739 } catch (RemoteException e) {
2740 // This shouldn't happen, but in this case fall back to outputting nothing
2741 Slog.e(TAG, e.toString());
2742 }
2743 }
2744
2745 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002746 public String toString() {
2747 if (stringName == null) {
2748 StringBuilder sb = new StringBuilder();
2749 sb.append("AppWindowToken{");
2750 sb.append(Integer.toHexString(System.identityHashCode(this)));
2751 sb.append(" token="); sb.append(token); sb.append('}');
2752 stringName = sb.toString();
2753 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002754 return stringName + ((mIsExiting) ? " mIsExiting=" : "");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002755 }
Adrian Roos20e07892018-02-23 19:12:01 +01002756
2757 Rect getLetterboxInsets() {
2758 if (mLetterbox != null) {
2759 return mLetterbox.getInsets();
2760 } else {
2761 return new Rect();
2762 }
2763 }
Adrian Roos23df3a32018-03-15 15:41:13 +01002764
2765 /**
2766 * @eturn true if there is a letterbox and any part of that letterbox overlaps with
2767 * the given {@code rect}.
2768 */
2769 boolean isLetterboxOverlappingWith(Rect rect) {
2770 return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
2771 }
chaviw4ad54912018-05-30 11:05:44 -07002772
2773 /**
2774 * Sets if this AWT is in the process of closing or entering PIP.
2775 * {@link #mWillCloseOrEnterPip}}
2776 */
2777 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
2778 mWillCloseOrEnterPip = willCloseOrEnterPip;
2779 }
2780
2781 /**
2782 * Returns whether this AWT is considered closing. Conditions are either
2783 * 1. Is this app animating and was requested to be hidden
2784 * 2. App is delayed closing since it might enter PIP.
2785 */
2786 boolean isClosingOrEnteringPip() {
2787 return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
2788 }
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +02002789
2790 /**
2791 * @return Whether we are allowed to show non-starting windows at the moment. We disallow
2792 * showing windows during transitions in case we have windows that have wide-color-gamut
2793 * color mode set to avoid jank in the middle of the transition.
2794 */
2795 boolean canShowWindows() {
2796 return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
2797 }
2798
2799 /**
2800 * @return true if we have a window that has a non-default color mode set; false otherwise.
2801 */
2802 private boolean hasNonDefaultColorWindow() {
2803 return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
2804 true /* topToBottom */);
2805 }
lumark588a3e82018-07-20 18:53:54 +08002806
2807 void removeFromPendingTransition() {
2808 if (isWaitingForTransitionStart() && mDisplayContent != null) {
2809 mDisplayContent.mOpeningApps.remove(this);
2810 mDisplayContent.mClosingApps.remove(this);
2811 }
2812 }
Jeff Browne9bdb312012-04-05 15:30:10 -07002813}