blob: df81c07ba530aaa95cb72a9980f446d9496f6f6f [file] [log] [blame]
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wm;
18
Winson Chunge55c0192017-08-24 14:50:48 -070019import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Jorim Jaggic6976f02018-04-18 16:31:07 +020020import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Winson Chunge55c0192017-08-24 14:50:48 -070021import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +020022import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
Wale Ogunwale72919d22016-12-08 18:58:50 -080023import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
24import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -070025import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
Wale Ogunwale51362492016-09-08 17:49:17 -070026import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020027import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070028import static android.view.Display.DEFAULT_DISPLAY;
Jorim Jaggife762342016-10-13 14:33:27 +020029import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020030import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080031import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020032import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070033import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080034import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070035import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080036import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
chaviw9c81e632018-07-31 11:17:52 -070037import static android.view.WindowManager.TRANSIT_UNSET;
Jorim Jaggic6976f02018-04-18 16:31:07 +020038import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
chaviw9c81e632018-07-31 11:17:52 -070039
Adrian Roose99bc052017-11-20 17:55:31 +010040import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
41import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070042import static com.android.server.wm.AppWindowTokenProto.ALL_DRAWN;
43import static com.android.server.wm.AppWindowTokenProto.APP_STOPPED;
44import static com.android.server.wm.AppWindowTokenProto.CLIENT_HIDDEN;
45import static com.android.server.wm.AppWindowTokenProto.DEFER_HIDING_CLIENT;
46import static com.android.server.wm.AppWindowTokenProto.FILLS_PARENT;
47import static com.android.server.wm.AppWindowTokenProto.FROZEN_BOUNDS;
48import static com.android.server.wm.AppWindowTokenProto.HIDDEN_REQUESTED;
49import static com.android.server.wm.AppWindowTokenProto.HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW;
50import static com.android.server.wm.AppWindowTokenProto.IS_REALLY_ANIMATING;
51import static com.android.server.wm.AppWindowTokenProto.IS_WAITING_FOR_TRANSITION_START;
52import static com.android.server.wm.AppWindowTokenProto.LAST_ALL_DRAWN;
53import static com.android.server.wm.AppWindowTokenProto.LAST_SURFACE_SHOWING;
54import static com.android.server.wm.AppWindowTokenProto.NAME;
55import static com.android.server.wm.AppWindowTokenProto.NUM_DRAWN_WINDOWS;
56import static com.android.server.wm.AppWindowTokenProto.NUM_INTERESTING_WINDOWS;
57import static com.android.server.wm.AppWindowTokenProto.REMOVED;
58import static com.android.server.wm.AppWindowTokenProto.REPORTED_DRAWN;
59import static com.android.server.wm.AppWindowTokenProto.REPORTED_VISIBLE;
60import static com.android.server.wm.AppWindowTokenProto.STARTING_DISPLAYED;
61import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED;
62import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
63import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
64import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
chaviw9c81e632018-07-31 11:17:52 -070065import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
67import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
68import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
69import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
70import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
71import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
72import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
73import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
74import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
75import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
76import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
77import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
78import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
79import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
80import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
81import static com.android.server.wm.WindowManagerService.logWithStack;
Vishnu Naira2977262018-07-26 13:31:26 -070082import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080083
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070084import android.annotation.CallSuper;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020085import android.app.Activity;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080086import android.app.ActivityManager;
Winson Chung48b25652018-10-22 14:04:30 -070087import android.content.ComponentName;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080088import android.content.res.CompatibilityInfo;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070089import android.content.res.Configuration;
Jorim Jaggi988f6682017-11-17 17:46:43 +010090import android.graphics.GraphicBuffer;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020091import android.graphics.Point;
Jorim Jaggi0429f352015-12-22 16:29:16 +010092import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070093import android.os.Binder;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -080094import android.os.Debug;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070095import android.os.IBinder;
Steven Timotiusaf03df62017-07-18 16:56:43 -070096import android.os.RemoteException;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080097import android.os.SystemClock;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020098import android.os.Trace;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080099import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700100import android.util.proto.ProtoOutputStream;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200101import android.view.DisplayInfo;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800102import android.view.IApplicationToken;
Robert Carr788f5742018-07-30 17:46:45 -0700103import android.view.InputApplicationHandle;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100104import android.view.RemoteAnimationDefinition;
Robert Carr6914f082017-03-20 19:04:30 -0700105import android.view.SurfaceControl;
Tony Mak64b8d562017-12-28 17:44:02 +0000106import android.view.SurfaceControl.Transaction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800107import android.view.WindowManager;
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200108import android.view.WindowManager.LayoutParams;
Tony Mak64b8d562017-12-28 17:44:02 +0000109import android.view.animation.Animation;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800110
Tony Mak64b8d562017-12-28 17:44:02 +0000111import com.android.internal.R;
Riddle Hsua118b3a2018-10-11 22:05:06 +0800112import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800113import com.android.internal.util.ToBooleanFunction;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800114import com.android.server.AttributeCache;
115import com.android.server.policy.WindowManagerPolicy;
Adrian Roose99bc052017-11-20 17:55:31 +0100116import com.android.server.policy.WindowManagerPolicy.StartingSurface;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800117import com.android.server.wm.WindowManagerService.H;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800118
119import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +0100120import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800121import java.util.ArrayList;
lumark588a3e82018-07-20 18:53:54 +0800122import java.util.function.Consumer;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800123
124class AppTokenList extends ArrayList<AppWindowToken> {
125}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800126
127/**
128 * Version of WindowToken that is specifically for a particular application (or
129 * really activity) that is displaying windows.
130 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800131class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener,
132 ConfigurationContainerListener {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800133 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
134
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100135 /**
136 * Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
137 */
138 private static final int Z_BOOST_BASE = 800570000;
139
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800140 // Non-null only for application tokens.
141 final IApplicationToken appToken;
Winson Chung48b25652018-10-22 14:04:30 -0700142 final ComponentName mActivityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800143 final boolean mVoiceInteraction;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700144
Wale Ogunwale51362492016-09-08 17:49:17 -0700145 /** @see WindowContainer#fillsParent() */
146 private boolean mFillsParent;
Craig Mautner4c5eb222013-11-18 12:59:05 -0800147 boolean layoutConfigChanges;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800148 boolean mShowForAllUsers;
149 int mTargetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -0700150
Bryce Lee6d410262017-02-28 15:30:17 -0800151 // Flag set while reparenting to prevent actions normally triggered by an individual parent
152 // change.
153 private boolean mReparenting;
154
Wale Ogunwalee287e192017-04-21 09:30:12 -0700155 // True if we are current in the process of removing this app token from the display
156 private boolean mRemovingFromDisplay = false;
157
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800158 // The input dispatching timeout for this application token in nanoseconds.
Wale Ogunwale72919d22016-12-08 18:58:50 -0800159 long mInputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800160
161 // These are used for determining when all windows associated with
162 // an activity have been drawn, so they can be made visible together
163 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -0700164 // initialize so that it doesn't match mTransactionSequence which is an int.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700165 private long mLastTransactionSequence = Long.MIN_VALUE;
166 private int mNumInterestingWindows;
167 private int mNumDrawnWindows;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800168 boolean inPendingTransaction;
169 boolean allDrawn;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000170 private boolean mLastAllDrawn;
171
Craig Mautner7636dfb2012-11-16 15:24:11 -0800172 // Set to true when this app creates a surface while in the middle of an animation. In that
173 // case do not clear allDrawn until the animation completes.
174 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800175
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800176 // Is this window's surface needed? This is almost like hidden, except
177 // it will sometimes be true a little earlier: when the token has
178 // been shown, but is still waiting for its app transition to execute
179 // before making its windows shown.
180 boolean hiddenRequested;
181
182 // Have we told the window clients to hide themselves?
Wale Ogunwale89973222017-04-23 18:39:45 -0700183 private boolean mClientHidden;
184
185 // If true we will defer setting mClientHidden to true and reporting to the client that it is
186 // hidden.
187 boolean mDeferHidingClient;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800188
189 // Last visibility state we reported to the app token.
190 boolean reportedVisible;
191
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700192 // Last drawn state we reported to the app token.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700193 private boolean reportedDrawn;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700194
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800195 // Set to true when the token has been removed from the window mgr.
196 boolean removed;
197
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800198 // Information about an application starting window if displayed.
199 StartingData startingData;
200 WindowState startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800201 StartingSurface startingSurface;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800202 boolean startingDisplayed;
203 boolean startingMoved;
Jorim Jaggi60f9c972018-02-01 19:21:07 +0100204
Wale Ogunwale6c459212017-05-17 08:56:03 -0700205 // True if the hidden state of this token was forced to false due to a transferred starting
206 // window.
207 private boolean mHiddenSetFromTransferredStartingWindow;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800208 boolean firstWindowDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700209 private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
210 new WindowState.UpdateReportedVisibilityResults();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800211
212 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700213 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800214
Wale Ogunwale571771c2016-08-26 13:18:50 -0700215 // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
Craig Mautner799bc1d2015-01-14 10:33:48 -0800216 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800217
Craig Mautnerbb742462014-07-07 15:28:55 -0700218 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700219 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700220
Wale Ogunwale72919d22016-12-08 18:58:50 -0800221 private boolean mAlwaysFocusable;
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800222
Robert Carre12aece2016-02-02 22:43:27 -0800223 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700224 int mRotationAnimationHint;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700225 private int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800226
Jorim Jaggife762342016-10-13 14:33:27 +0200227 private boolean mLastContainsShowWhenLockedWindow;
228 private boolean mLastContainsDismissKeyguardWindow;
229
Jorim Jaggi0429f352015-12-22 16:29:16 +0100230 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700231 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100232
Wale Ogunwale6c459212017-05-17 08:56:03 -0700233 private boolean mDisablePreviewScreenshots;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +0100234
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700235 private Task mLastParent;
Robert Carred3e83b2017-04-21 13:26:55 -0700236
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800237 // TODO: Remove after unification
238 ActivityRecord mActivityRecord;
239
chaviwd3bf08d2017-08-01 17:24:59 -0700240 /**
241 * See {@link #canTurnScreenOn()}
242 */
243 private boolean mCanTurnScreenOn = true;
244
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200245 /**
246 * If we are running an animation, this determines the transition type. Must be one of
247 * AppTransition.TRANSIT_* constants.
248 */
249 private int mTransit;
250
251 /**
252 * If we are running an animation, this determines the flags during this animation. Must be a
253 * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
254 */
255 private int mTransitFlags;
256
257 /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
Jorim Jaggifd1891462017-12-29 15:41:36 +0100258 private boolean mLastSurfaceShowing = true;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200259
Jorim Jaggi988f6682017-11-17 17:46:43 +0100260 private AppWindowThumbnail mThumbnail;
261
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000262 /** Have we been asked to have this token keep the screen frozen? */
263 private boolean mFreezingScreen;
264
265 /** Whether this token should be boosted at the top of all app window tokens. */
266 private boolean mNeedsZBoost;
Adrian Roos4d18a2e2017-12-19 19:08:05 +0100267 private Letterbox mLetterbox;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000268
chaviw23ee71c2017-12-18 11:29:41 -0800269 private final Point mTmpPoint = new Point();
chaviw23012112017-12-20 15:29:04 -0800270 private final Rect mTmpRect = new Rect();
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100271 private RemoteAnimationDefinition mRemoteAnimationDefinition;
Jorim Jaggi6de61012018-03-19 14:53:23 +0100272 private AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry;
chaviw23ee71c2017-12-18 11:29:41 -0800273
chaviw4ad54912018-05-30 11:05:44 -0700274 /**
275 * A flag to determine if this AWT is in the process of closing or entering PIP. This is needed
276 * to help AWT know that the app is in the process of closing but hasn't yet started closing on
277 * the WM side.
278 */
279 private boolean mWillCloseOrEnterPip;
280
Vishnu Naira2977262018-07-26 13:31:26 -0700281 /** Layer used to constrain the animation to a token's stack bounds. */
282 SurfaceControl mAnimationBoundsLayer;
283
284 /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
285 boolean mNeedsAnimationBoundsLayer;
286
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800287 private static final int STARTING_WINDOW_TYPE_NONE = 0;
288 private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
289 private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
290
Winson Chung48b25652018-10-22 14:04:30 -0700291 AppWindowToken(WindowManagerService service, IApplicationToken token,
292 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
293 long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
294 int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
295 boolean launchTaskBehind, boolean alwaysFocusable,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800296 ActivityRecord activityRecord) {
Winson Chung48b25652018-10-22 14:04:30 -0700297 this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800298 // TODO: remove after unification
299 mActivityRecord = activityRecord;
300 mActivityRecord.registerConfigurationChangeListener(this);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800301 mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800302 mShowForAllUsers = showForAllUsers;
303 mTargetSdk = targetSdk;
304 mOrientation = orientation;
305 layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0;
306 mLaunchTaskBehind = launchTaskBehind;
307 mAlwaysFocusable = alwaysFocusable;
308 mRotationAnimationHint = rotationAnimationHint;
309
310 // Application tokens start out hidden.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200311 setHidden(true);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800312 hiddenRequested = true;
313 }
314
Winson Chung48b25652018-10-22 14:04:30 -0700315 AppWindowToken(WindowManagerService service, IApplicationToken token,
316 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
317 boolean fillsParent) {
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800318 super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
319 false /* ownerCanManageAppTokens */);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700320 appToken = token;
Winson Chung48b25652018-10-22 14:04:30 -0700321 mActivityComponent = activityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800322 mVoiceInteraction = voiceInteraction;
Wale Ogunwale17f175c2017-02-07 16:54:10 -0800323 mFillsParent = fillsParent;
Robert Carr0bcbe642018-10-11 19:07:43 -0700324 mInputApplicationHandle = new InputApplicationHandle(appToken.asBinder());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800325 }
326
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800327 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
328 firstWindowDrawn = true;
329
330 // We now have a good window to show, remove dead placeholders
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700331 removeDeadWindows();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800332
Jorim Jaggi02886a82016-12-06 09:10:06 -0800333 if (startingWindow != null) {
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800334 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
335 + win.mToken + ": first real window is shown, no animation");
336 // If this initial window is animating, stop it -- we will do an animation to reveal
337 // it from behind the starting window, so there is no need for it to also be doing its
338 // own stuff.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100339 win.cancelAnimation();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800340 removeStartingWindow();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800341 }
342 updateReportedVisibilityLocked();
343 }
344
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800345 void updateReportedVisibilityLocked() {
346 if (appToken == null) {
347 return;
348 }
349
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700350 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700351 final int count = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800352
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700353 mReportedVisibilityResults.reset();
354
355 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700356 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700357 win.updateReportedVisibility(mReportedVisibilityResults);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800358 }
359
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700360 int numInteresting = mReportedVisibilityResults.numInteresting;
361 int numVisible = mReportedVisibilityResults.numVisible;
362 int numDrawn = mReportedVisibilityResults.numDrawn;
363 boolean nowGone = mReportedVisibilityResults.nowGone;
364
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700365 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200366 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !isHidden();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700367 if (!nowGone) {
368 // If the app is not yet gone, then it can only become visible/drawn.
369 if (!nowDrawn) {
370 nowDrawn = reportedDrawn;
371 }
372 if (!nowVisible) {
373 nowVisible = reportedVisible;
374 }
375 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800376 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800377 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700378 if (nowDrawn != reportedDrawn) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800379 if (mActivityRecord != null) {
380 mActivityRecord.onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700381 }
382 reportedDrawn = nowDrawn;
383 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800384 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700385 if (DEBUG_VISIBILITY) Slog.v(TAG,
386 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800387 reportedVisible = nowVisible;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800388 if (mActivityRecord != null) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800389 if (nowVisible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800390 onWindowsVisible();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800391 } else {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800392 onWindowsGone();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800393 }
394 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800395 }
396 }
397
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800398 private void onWindowsGone() {
399 if (mActivityRecord == null) {
400 return;
401 }
402 if (DEBUG_VISIBILITY) {
403 Slog.v(TAG_WM, "Reporting gone in " + mActivityRecord.appToken);
404 }
405 mActivityRecord.onWindowsGone();
406 }
407
408 private void onWindowsVisible() {
409 if (mActivityRecord == null) {
410 return;
411 }
412 if (DEBUG_VISIBILITY) {
413 Slog.v(TAG_WM, "Reporting visible in " + mActivityRecord.appToken);
414 }
415 mActivityRecord.onWindowsVisible();
416 }
417
Wale Ogunwale89973222017-04-23 18:39:45 -0700418 boolean isClientHidden() {
419 return mClientHidden;
420 }
421
422 void setClientHidden(boolean hideClient) {
423 if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
424 return;
425 }
Jorim Jaggi067b5bf2018-02-23 17:42:39 +0100426 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
427 + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
Wale Ogunwale89973222017-04-23 18:39:45 -0700428 mClientHidden = hideClient;
429 sendAppVisibilityToClients();
430 }
431
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800432 void setVisibility(boolean visible, boolean deferHidingClient) {
433 final AppTransition appTransition = getDisplayContent().mAppTransition;
434
435 // Don't set visibility to false if we were already not visible. This prevents WM from
436 // adding the app to the closing app list which doesn't make sense for something that is
437 // already not visible. However, set visibility to true even if we are already visible.
438 // This makes sure the app is added to the opening apps list so that the right
439 // transition can be selected.
440 // TODO: Probably a good idea to separate the concept of opening/closing apps from the
441 // concept of setting visibility...
442 if (!visible && hiddenRequested) {
443
444 if (!deferHidingClient && mDeferHidingClient) {
445 // We previously deferred telling the client to hide itself when visibility was
446 // initially set to false. Now we would like it to hide, so go ahead and set it.
447 mDeferHidingClient = deferHidingClient;
448 setClientHidden(true);
449 }
450 return;
451 }
452
453 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
454 Slog.v(TAG_WM, "setAppVisibility("
455 + appToken + ", visible=" + visible + "): " + appTransition
456 + " hidden=" + isHidden() + " hiddenRequested="
457 + hiddenRequested + " Callers=" + Debug.getCallers(6));
458 }
459
460 final DisplayContent displayContent = getDisplayContent();
461 displayContent.mOpeningApps.remove(this);
462 displayContent.mClosingApps.remove(this);
463 waitingToShow = false;
464 hiddenRequested = !visible;
465 mDeferHidingClient = deferHidingClient;
466
467 if (!visible) {
468 // If the app is dead while it was visible, we kept its dead window on screen.
469 // Now that the app is going invisible, we can remove it. It will be restarted
470 // if made visible again.
471 removeDeadWindows();
472 } else {
473 if (!appTransition.isTransitionSet()
474 && appTransition.isReady()) {
475 // Add the app mOpeningApps if transition is unset but ready. This means
476 // we're doing a screen freeze, and the unfreeze will wait for all opening
477 // apps to be ready.
478 displayContent.mOpeningApps.add(this);
479 }
480 startingMoved = false;
481 // If the token is currently hidden (should be the common case), or has been
482 // stopped, then we need to set up to wait for its windows to be ready.
483 if (isHidden() || mAppStopped) {
484 clearAllDrawn();
485
486 // If the app was already visible, don't reset the waitingToShow state.
487 if (isHidden()) {
488 waitingToShow = true;
489 }
490 }
491
492 // In the case where we are making an app visible but holding off for a transition,
493 // we still need to tell the client to make its windows visible so they get drawn.
494 // Otherwise, we will wait on performing the transition until all windows have been
495 // drawn, they never will be, and we are sad.
496 setClientHidden(false);
497
498 requestUpdateWallpaperIfNeeded();
499
500 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + this);
501 mAppStopped = false;
502
503 transferStartingWindowFromHiddenAboveTokenIfNeeded();
504 }
505
506 // If we are preparing an app transition, then delay changing
507 // the visibility of this token until we execute that transition.
508 if (okToAnimate() && appTransition.isTransitionSet()) {
509 inPendingTransaction = true;
510 if (visible) {
511 displayContent.mOpeningApps.add(this);
512 mEnteringAnimation = true;
513 } else {
514 displayContent.mClosingApps.add(this);
515 mEnteringAnimation = false;
516 }
517 if (appTransition.getAppTransition()
518 == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
519 // We're launchingBehind, add the launching activity to mOpeningApps.
520 final WindowState win = getDisplayContent().findFocusedWindow();
521 if (win != null) {
522 final AppWindowToken focusedToken = win.mAppToken;
523 if (focusedToken != null) {
524 if (DEBUG_APP_TRANSITIONS) {
525 Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
526 + " adding " + focusedToken + " to mOpeningApps");
527 }
528 // Force animation to be loaded.
529 focusedToken.setHidden(true);
530 displayContent.mOpeningApps.add(focusedToken);
531 }
532 }
533 }
534 return;
535 }
536
537 commitVisibility(null, visible, TRANSIT_UNSET, true, mVoiceInteraction);
538 updateReportedVisibilityLocked();
539 }
540
541 boolean commitVisibility(WindowManager.LayoutParams lp,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700542 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
543
544 boolean delayed = false;
545 inPendingTransaction = false;
Wale Ogunwale9e4721f2017-05-23 19:37:30 -0700546 // Reset the state of mHiddenSetFromTransferredStartingWindow since visibility is actually
547 // been set by the app now.
548 mHiddenSetFromTransferredStartingWindow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700549
550 // Allow for state changes and animation to be applied if:
551 // * token is transitioning visibility state
552 // * or the token was marked as hidden and is exiting before we had a chance to play the
553 // transition animation
554 // * or this is an opening app and windows are being replaced.
555 boolean visibilityChanged = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200556 if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700557 final AccessibilityController accessibilityController = mService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700558 boolean changed = false;
559 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200560 "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700561
562 boolean runningAppAnimation = false;
563
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100564 if (transit != WindowManager.TRANSIT_UNSET) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200565 if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700566 delayed = runningAppAnimation = true;
567 }
568 final WindowState window = findMainWindow();
569 //TODO (multidisplay): Magnification is supported only for the default display.
570 if (window != null && accessibilityController != null
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700571 && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700572 accessibilityController.onAppWindowTransitionLocked(window, transit);
573 }
574 changed = true;
575 }
576
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700577 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700578 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700579 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700580 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700581 }
582
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200583 setHidden(!visible);
584 hiddenRequested = !visible;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700585 visibilityChanged = true;
586 if (!visible) {
587 stopFreezingScreen(true, true);
588 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700589 // If we are being set visible, and the starting window is not yet displayed,
590 // then make sure it doesn't get displayed.
591 if (startingWindow != null && !startingWindow.isDrawnLw()) {
592 startingWindow.mPolicyVisibility = false;
593 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700594 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -0700595
596 // We are becoming visible, so better freeze the screen with the windows that are
597 // getting visible so we also wait for them.
598 forAllWindows(mService::makeWindowFreezingScreenIfNeededLocked, true);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700599 }
600
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800601 if (DEBUG_APP_TRANSITIONS) {
602 Slog.v(TAG_WM, "commitVisibility: " + this
603 + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
604 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700605
606 if (changed) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800607 getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700608 if (performLayout) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700609 mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700610 false /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700611 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700612 }
Arthur Hung95b38a92018-07-20 18:56:12 +0800613 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700614 }
615 }
616
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200617 if (isReallyAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700618 delayed = true;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100619 } else {
620
621 // We aren't animating anything, but exiting windows rely on the animation finished
622 // callback being called in case the AppWindowToken was pretending to be animating,
623 // which we might have done because we were in closing/opening apps list.
624 onAnimationFinished();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700625 }
626
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700627 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100628 if ((mChildren.get(i)).isSelfOrChildAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700629 delayed = true;
630 }
631 }
632
633 if (visibilityChanged) {
634 if (visible && !delayed) {
635 // The token was made immediately visible, there will be no entrance animation.
636 // We need to inform the client the enter animation was finished.
637 mEnteringAnimation = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700638 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700639 }
Robert Carr61b81112017-07-17 18:08:15 -0700640
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800641 // If we're becoming visible, immediately change client visibility as well. there seem
642 // to be some edge cases where we change our visibility but client visibility never gets
643 // updated.
Jorim Jaggi110839b2018-01-22 12:49:04 +0100644 // If we're becoming invisible, update the client visibility if we are not running an
645 // animation. Otherwise, we'll update client visibility in onAnimationFinished.
Jorim Jaggi3cad57f2018-02-20 18:32:01 +0100646 if (visible || !isReallyAnimating()) {
Jorim Jaggi110839b2018-01-22 12:49:04 +0100647 setClientHidden(!visible);
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100648 }
649
lumark588a3e82018-07-20 18:53:54 +0800650 if (!getDisplayContent().mClosingApps.contains(this)
651 && !getDisplayContent().mOpeningApps.contains(this)) {
chaviwa953fcf2018-03-01 12:00:39 -0800652 // The token is not closing nor opening, so even if there is an animation set, that
653 // doesn't mean that it goes through the normal app transition cycle so we have
654 // to inform the docked controller about visibility change.
655 // TODO(multi-display): notify docked divider on all displays where visibility was
656 // affected.
lumark588a3e82018-07-20 18:53:54 +0800657 getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged();
chaviwa953fcf2018-03-01 12:00:39 -0800658
659 // Take the screenshot before possibly hiding the WSA, otherwise the screenshot
660 // will not be taken.
661 mService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
662 }
663
Robert Carre7cc44d2017-03-20 19:04:30 -0700664 // If we are hidden but there is no delay needed we immediately
665 // apply the Surface transaction so that the ActivityManager
Robert Carr61b81112017-07-17 18:08:15 -0700666 // can have some guarantee on the Surface state following
667 // setting the visibility. This captures cases like dismissing
668 // the docked or pinned stack where there is no app transition.
669 //
670 // In the case of a "Null" animation, there will be
671 // no animation but there will still be a transition set.
672 // We still need to delay hiding the surface such that it
673 // can be synchronized with showing the next surface in the transition.
lumark588a3e82018-07-20 18:53:54 +0800674 if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) {
Robert Carr6914f082017-03-20 19:04:30 -0700675 SurfaceControl.openTransaction();
676 for (int i = mChildren.size() - 1; i >= 0; i--) {
677 mChildren.get(i).mWinAnimator.hide("immediately hidden");
678 }
679 SurfaceControl.closeTransaction();
680 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700681 }
682
683 return delayed;
684 }
685
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200686 /**
687 * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns
688 * true.
689 */
690 WindowState getTopFullscreenWindow() {
691 for (int i = mChildren.size() - 1; i >= 0; i--) {
692 final WindowState win = mChildren.get(i);
693 if (win != null && win.mAttrs.isFullscreen()) {
694 return win;
695 }
696 }
697 return null;
698 }
699
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800700 WindowState findMainWindow() {
Matthew Ng53e66b22018-01-12 17:13:13 -0800701 return findMainWindow(true);
702 }
703
704 /**
705 * Finds the main window that either has type base application or application starting if
706 * requested.
707 *
708 * @param includeStartingApp Allow to search application-starting windows to also be returned.
709 * @return The main window of type base application or application starting if requested.
710 */
711 WindowState findMainWindow(boolean includeStartingApp) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700712 WindowState candidate = null;
Matthew Ng53e66b22018-01-12 17:13:13 -0800713 for (int j = mChildren.size() - 1; j >= 0; --j) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700714 final WindowState win = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700715 final int type = win.mAttrs.type;
716 // No need to loop through child window as base application and starting types can't be
717 // child windows.
Matthew Ng53e66b22018-01-12 17:13:13 -0800718 if (type == TYPE_BASE_APPLICATION
719 || (includeStartingApp && type == TYPE_APPLICATION_STARTING)) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700720 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900721 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700722 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800723 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700724 candidate = win;
725 } else {
726 return win;
727 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800728 }
729 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700730 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800731 }
732
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800733 boolean windowsAreFocusable() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700734 return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800735 }
736
Wale Ogunwale571771c2016-08-26 13:18:50 -0700737 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700738 boolean isVisible() {
Wale Ogunwalee471be62016-10-03 07:53:55 -0700739 // If the app token isn't hidden then it is considered visible and there is no need to check
740 // its children windows to see if they are visible.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200741 return !isHidden();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700742 }
743
744 @Override
Wale Ogunwalee287e192017-04-21 09:30:12 -0700745 void removeImmediately() {
746 onRemovedFromDisplay();
747 super.removeImmediately();
748 }
749
750 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700751 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800752 mIsExiting = false;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800753 removeAllWindowsIfPossible();
Bryce Lee6d410262017-02-28 15:30:17 -0800754 removeImmediately();
Craig Mautnere3119b72015-01-20 15:02:36 -0800755 }
756
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700757 @Override
758 boolean checkCompleteDeferredRemoval() {
759 if (mIsExiting) {
760 removeIfPossible();
761 }
762 return super.checkCompleteDeferredRemoval();
763 }
764
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700765 void onRemovedFromDisplay() {
Wale Ogunwalee287e192017-04-21 09:30:12 -0700766 if (mRemovingFromDisplay) {
767 return;
768 }
769 mRemovingFromDisplay = true;
770
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700771 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
772
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800773 boolean delayed = commitVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700774
lumark588a3e82018-07-20 18:53:54 +0800775 getDisplayContent().mOpeningApps.remove(this);
776 getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
Jorim Jaggi10abe2f2017-01-03 16:44:46 +0100777 mService.mTaskSnapshotController.onAppRemoved(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700778 waitingToShow = false;
lumark588a3e82018-07-20 18:53:54 +0800779 if (getDisplayContent().mClosingApps.contains(this)) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700780 delayed = true;
lumark588a3e82018-07-20 18:53:54 +0800781 } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
782 getDisplayContent().mClosingApps.add(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700783 delayed = true;
784 }
785
786 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200787 + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700788
789 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
790 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
791
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800792 if (startingData != null) {
793 removeStartingWindow();
Jorim Jaggi19be6052017-08-03 18:33:43 +0200794 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800795
Winson Chung87e5d552017-04-05 11:49:38 -0700796 // If this window was animating, then we need to ensure that the app transition notifies
lumark588a3e82018-07-20 18:53:54 +0800797 // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
798 // so add to that list now
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200799 if (isSelfAnimating()) {
lumark588a3e82018-07-20 18:53:54 +0800800 getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
Winson Chung87e5d552017-04-05 11:49:38 -0700801 }
802
Wale Ogunwalee287e192017-04-21 09:30:12 -0700803 final TaskStack stack = getStack();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700804 if (delayed && !isEmpty()) {
805 // set the token aside because it has an active animation to be finished
806 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
807 "removeAppToken make exiting: " + this);
Wale Ogunwalee287e192017-04-21 09:30:12 -0700808 if (stack != null) {
809 stack.mExitingAppTokens.add(this);
810 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700811 mIsExiting = true;
812 } else {
813 // Make sure there is no animation running on this token, so any windows associated
814 // with it will be removed as soon as their animations are complete
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200815 cancelAnimation();
Wale Ogunwale3106ae012017-05-16 08:56:37 -0700816 if (stack != null) {
817 stack.mExitingAppTokens.remove(this);
818 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700819 removeIfPossible();
820 }
821
822 removed = true;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700823 stopFreezingScreen(true, true);
Bryce Lee6d410262017-02-28 15:30:17 -0800824
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800825 final DisplayContent dc = getDisplayContent();
826 if (dc.mFocusedApp == this) {
827 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
828 + " displayId=" + dc.getDisplayId());
829 dc.setFocusedApp(null);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700830 mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700831 }
832
833 if (!delayed) {
834 updateReportedVisibilityLocked();
835 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700836
837 mRemovingFromDisplay = false;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700838 }
839
Chong Zhange05bcb12016-07-26 17:47:29 -0700840 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700841 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700842 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700843 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700844 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700845 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700846 if (wallpaperMightChange) {
847 requestUpdateWallpaperIfNeeded();
848 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700849 }
850
Robert Carre12aece2016-02-02 22:43:27 -0800851 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700852 destroySurfaces(false /*cleanupOnResume*/);
853 }
854
855 /**
856 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
857 * the client has finished with them.
858 *
859 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
860 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
861 * others so that they are ready to be reused. If set to false (common case), destroy all
862 * surfaces that's eligible, if the app is already stopped.
863 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700864 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700865 boolean destroyedSomething = false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100866
867 // Copying to a different list as multiple children can be removed.
Jorim Jaggi59f3e922018-01-05 15:40:32 +0100868 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100869 for (int i = children.size() - 1; i >= 0; i--) {
870 final WindowState win = children.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700871 destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
Robert Carre12aece2016-02-02 22:43:27 -0800872 }
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700873 if (destroyedSomething) {
874 final DisplayContent dc = getDisplayContent();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700875 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Adrian Roos23df3a32018-03-15 15:41:13 +0100876 updateLetterboxSurface(null);
Robert Carre12aece2016-02-02 22:43:27 -0800877 }
878 }
879
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800880 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700881 * Notify that the app is now resumed, and it was not stopped before, perform a clean
882 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800883 */
Jorim Jaggibae01b12017-04-11 16:29:10 -0700884 void notifyAppResumed(boolean wasStopped) {
Chong Zhangad24f962016-08-25 12:12:33 -0700885 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
Jorim Jaggibae01b12017-04-11 16:29:10 -0700886 + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700887 mAppStopped = false;
chaviwd3bf08d2017-08-01 17:24:59 -0700888 // Allow the window to turn the screen on once the app is resumed again.
889 setCanTurnScreenOn(true);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700890 if (!wasStopped) {
891 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800892 }
Robert Carre12aece2016-02-02 22:43:27 -0800893 }
894
Chong Zhangbef461f2015-10-27 11:38:24 -0700895 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700896 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
897 * keeping alive in case they were still being used.
898 */
899 void notifyAppStopped() {
900 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
901 mAppStopped = true;
902 destroySurfaces();
903 // Remove any starting window that was added for this app if they are still around.
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800904 removeStartingWindow();
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700905 }
906
Chong Zhang92147042016-05-09 12:47:11 -0700907 void clearAllDrawn() {
908 allDrawn = false;
909 deferClearAllDrawn = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700910 }
911
Bryce Lee6d410262017-02-28 15:30:17 -0800912 Task getTask() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800913 return (Task) getParent();
Bryce Lee6d410262017-02-28 15:30:17 -0800914 }
915
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800916 TaskStack getStack() {
917 final Task task = getTask();
918 if (task != null) {
919 return task.mStack;
920 } else {
921 return null;
922 }
923 }
924
Bryce Lee6d410262017-02-28 15:30:17 -0800925 @Override
926 void onParentSet() {
927 super.onParentSet();
928
Robert Carred3e83b2017-04-21 13:26:55 -0700929 final Task task = getTask();
930
Bryce Lee6d410262017-02-28 15:30:17 -0800931 // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
932 // access visual elements like the {@link DisplayContent}. We must remove any associations
933 // such as animations.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800934 if (!mReparenting) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800935 if (task == null) {
936 // It is possible we have been marked as a closing app earlier. We must remove ourselves
937 // from this list so we do not participate in any future animations.
lumark588a3e82018-07-20 18:53:54 +0800938 getDisplayContent().mClosingApps.remove(this);
Robert Carred3e83b2017-04-21 13:26:55 -0700939 } else if (mLastParent != null && mLastParent.mStack != null) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800940 task.mStack.mExitingAppTokens.remove(this);
941 }
Bryce Lee6d410262017-02-28 15:30:17 -0800942 }
Jorim Jaggi6de61012018-03-19 14:53:23 +0100943 final TaskStack stack = getStack();
944
945 // If we reparent, make sure to remove ourselves from the old animation registry.
946 if (mAnimatingAppWindowTokenRegistry != null) {
947 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
948 }
949 mAnimatingAppWindowTokenRegistry = stack != null
950 ? stack.getAnimatingAppWindowTokenRegistry()
951 : null;
952
Robert Carred3e83b2017-04-21 13:26:55 -0700953 mLastParent = task;
Bryce Lee6d410262017-02-28 15:30:17 -0800954 }
955
Wale Ogunwalefa854eb2016-09-20 13:43:52 -0700956 void postWindowRemoveStartingWindowCleanup(WindowState win) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700957 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700958 if (startingWindow == win) {
959 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800960 removeStartingWindow();
Wale Ogunwale6c459212017-05-17 08:56:03 -0700961 } else if (mChildren.size() == 0) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700962 // If this is the last window and we had requested a starting transition window,
963 // well there is no point now.
Jorim Jaggi02886a82016-12-06 09:10:06 -0800964 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700965 startingData = null;
Wale Ogunwale6c459212017-05-17 08:56:03 -0700966 if (mHiddenSetFromTransferredStartingWindow) {
967 // We set the hidden state to false for the token from a transferred starting window.
968 // We now reset it back to true since the starting window was the last window in the
969 // token.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200970 setHidden(true);
Wale Ogunwale6c459212017-05-17 08:56:03 -0700971 }
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100972 } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700973 // If this is the last window except for a starting transition window,
974 // we need to get rid of the starting transition.
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200975 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
976 + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800977 removeStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700978 }
979 }
980
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700981 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700982 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700983 WindowState win = mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800984 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700985 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700986 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800987 // Set mDestroying, we don't want any animation or delayed removal here.
988 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700989 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700990 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800991 }
992 }
993 }
994
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700995 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700996 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700997 // No need to loop through child windows as the answer should be the same as that of the
998 // parent window.
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700999 if (!(mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001000 return true;
1001 }
1002 }
1003 return false;
1004 }
1005
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001006 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001007 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1008 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -08001009
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001010 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001011 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001012 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -08001013 }
Robert Carra1eb4392015-12-10 12:43:51 -08001014 }
1015
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001016 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001017 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -08001018 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001019 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001020 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001021 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -08001022 }
1023 }
1024
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001025 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001026 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1027 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -08001028
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001029 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001030 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001031 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -08001032 }
1033 }
1034
Chong Zhang4d7369a2016-04-25 16:09:14 -07001035 void requestUpdateWallpaperIfNeeded() {
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);
Chong Zhang4d7369a2016-04-25 16:09:14 -07001038 w.requestUpdateWallpaperIfNeeded();
1039 }
1040 }
1041
Chong Zhangd78ddb42016-03-02 17:01:14 -08001042 boolean isRelaunching() {
1043 return mPendingRelaunchCount > 0;
1044 }
1045
Robert Carr68375192017-06-13 12:41:53 -07001046 boolean shouldFreezeBounds() {
1047 final Task task = getTask();
1048
1049 // For freeform windows, we can't freeze the bounds at the moment because this would make
1050 // the resizing unresponsive.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001051 if (task == null || task.inFreeformWindowingMode()) {
Robert Carr68375192017-06-13 12:41:53 -07001052 return false;
1053 }
1054
1055 // We freeze the bounds while drag resizing to deal with the time between
1056 // the divider/drag handle being released, and the handling it's new
1057 // configuration. If we are relaunched outside of the drag resizing state,
1058 // we need to be careful not to do this.
1059 return getTask().isDragResizing();
1060 }
1061
Chong Zhangd78ddb42016-03-02 17:01:14 -08001062 void startRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001063 if (shouldFreezeBounds()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001064 freezeBounds();
1065 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001066
1067 // In the process of tearing down before relaunching, the app will
1068 // try and clean up it's child surfaces. We need to prevent this from
1069 // happening, so we sever the children, transfering their ownership
1070 // from the client it-self to the parent surface (owned by us).
Robert Carr29daa922018-04-27 11:56:48 -07001071 detachChildren();
1072
1073 mPendingRelaunchCount++;
1074 }
1075
1076 void detachChildren() {
Robert Carrfd8e93b2018-05-10 13:40:25 -07001077 SurfaceControl.openTransaction();
Robert Carrd5c7dd62017-03-08 10:39:30 -08001078 for (int i = mChildren.size() - 1; i >= 0; i--) {
1079 final WindowState w = mChildren.get(i);
1080 w.mWinAnimator.detachChildren();
1081 }
Robert Carrfd8e93b2018-05-10 13:40:25 -07001082 SurfaceControl.closeTransaction();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001083 }
1084
1085 void finishRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001086 unfreezeBounds();
1087
Chong Zhangd78ddb42016-03-02 17:01:14 -08001088 if (mPendingRelaunchCount > 0) {
1089 mPendingRelaunchCount--;
Bryce Lee081554b2017-05-25 07:52:12 -07001090 } else {
1091 // Update keyguard flags upon finishing relaunch.
1092 checkKeyguardFlagsChanged();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001093 }
1094 }
1095
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001096 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001097 if (mPendingRelaunchCount == 0) {
1098 return;
1099 }
Robert Carr68375192017-06-13 12:41:53 -07001100 unfreezeBounds();
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001101 mPendingRelaunchCount = 0;
1102 }
1103
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001104 /**
1105 * Returns true if the new child window we are adding to this token is considered greater than
1106 * the existing child window in this token in terms of z-order.
1107 */
1108 @Override
1109 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
1110 WindowState existingWindow) {
1111 final int type1 = newWindow.mAttrs.type;
1112 final int type2 = existingWindow.mAttrs.type;
1113
1114 // Base application windows should be z-ordered BELOW all other windows in the app token.
1115 if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
1116 return false;
1117 } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
1118 return true;
1119 }
1120
1121 // Starting windows should be z-ordered ABOVE all other windows in the app token.
1122 if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
1123 return true;
1124 } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
1125 return false;
1126 }
1127
1128 // Otherwise the new window is greater than the existing window.
1129 return true;
1130 }
1131
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001132 @Override
Robert Carra1eb4392015-12-10 12:43:51 -08001133 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001134 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001135
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001136 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001137 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001138 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001139 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
1140 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001141
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001142 // if we got a replacement window, reset the timeout to give drawing more time
1143 if (gotReplacementWindow) {
1144 mService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -08001145 }
Jorim Jaggife762342016-10-13 14:33:27 +02001146 checkKeyguardFlagsChanged();
1147 }
1148
1149 @Override
1150 void removeChild(WindowState child) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001151 if (!mChildren.contains(child)) {
1152 // This can be true when testing.
1153 return;
1154 }
Jorim Jaggife762342016-10-13 14:33:27 +02001155 super.removeChild(child);
1156 checkKeyguardFlagsChanged();
Adrian Roos23df3a32018-03-15 15:41:13 +01001157 updateLetterboxSurface(child);
Robert Carra1eb4392015-12-10 12:43:51 -08001158 }
1159
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001160 private boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001161 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001162 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001163 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -08001164 return true;
1165 }
1166 }
1167 return false;
1168 }
1169
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001170 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001171 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001172 (mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -08001173 }
1174 }
1175
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001176 void reparent(TaskWindowContainerController taskController, int position) {
1177 if (DEBUG_ADD_REMOVE) {
1178 Slog.i(TAG_WM, "reparent: moving app token=" + this
1179 + " to task=" + taskController + " at " + position);
1180 }
1181 final Task task = taskController.mContainer;
1182 if (task == null) {
1183 throw new IllegalArgumentException("reparent: could not find task="
1184 + taskController);
1185 }
1186 reparent(task, position);
1187 getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
1188 }
1189
Winson Chung30480042017-01-26 10:55:34 -08001190 void reparent(Task task, int position) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001191 final Task currentTask = getTask();
1192 if (task == currentTask) {
Winson Chung30480042017-01-26 10:55:34 -08001193 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001194 "window token=" + this + " already child of task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001195 }
Bryce Lee6d410262017-02-28 15:30:17 -08001196
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001197 if (currentTask.mStack != task.mStack) {
Bryce Lee6d410262017-02-28 15:30:17 -08001198 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001199 "window token=" + this + " current task=" + currentTask
Bryce Lee6d410262017-02-28 15:30:17 -08001200 + " belongs to a different stack than " + task);
1201 }
1202
Winson Chung30480042017-01-26 10:55:34 -08001203 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001204 + " from task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001205 final DisplayContent prevDisplayContent = getDisplayContent();
1206
Bryce Lee6d410262017-02-28 15:30:17 -08001207 mReparenting = true;
1208
Winson Chung30480042017-01-26 10:55:34 -08001209 getParent().removeChild(this);
1210 task.addChild(this, position);
1211
Bryce Lee6d410262017-02-28 15:30:17 -08001212 mReparenting = false;
1213
Winson Chung30480042017-01-26 10:55:34 -08001214 // Relayout display(s).
1215 final DisplayContent displayContent = task.getDisplayContent();
1216 displayContent.setLayoutNeeded();
1217 if (prevDisplayContent != displayContent) {
1218 onDisplayChanged(displayContent);
1219 prevDisplayContent.setLayoutNeeded();
1220 }
1221 }
1222
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001223 @Override
1224 void onDisplayChanged(DisplayContent dc) {
1225 DisplayContent prevDc = mDisplayContent;
1226 super.onDisplayChanged(dc);
1227 if (prevDc != null && prevDc.mFocusedApp == this) {
1228 prevDc.setFocusedApp(null);
lumarkbf844642018-11-23 17:11:36 +08001229 final TaskStack stack = dc.getTopStack();
1230 if (stack != null) {
1231 final Task task = stack.getTopChild();
1232 if (task != null && task.getTopChild() == this) {
1233 dc.setFocusedApp(this);
1234 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001235 }
1236 }
1237 }
1238
Jorim Jaggi0429f352015-12-22 16:29:16 +01001239 /**
1240 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
1241 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
1242 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
1243 * with a queue.
1244 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001245 private void freezeBounds() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001246 final Task task = getTask();
1247 mFrozenBounds.offer(new Rect(task.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001248
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001249 if (task.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001250 // We didn't call prepareFreezingBounds on the task, so use the current value.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001251 mFrozenMergedConfig.offer(new Configuration(task.getConfiguration()));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001252 } else {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001253 mFrozenMergedConfig.offer(new Configuration(task.mPreparedFrozenMergedConfig));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001254 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001255 // Calling unset() to make it equal to Configuration.EMPTY.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001256 task.mPreparedFrozenMergedConfig.unset();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001257 }
1258
1259 /**
1260 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
1261 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001262 private void unfreezeBounds() {
Robert Carr68375192017-06-13 12:41:53 -07001263 if (mFrozenBounds.isEmpty()) {
1264 return;
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001265 }
Robert Carr68375192017-06-13 12:41:53 -07001266 mFrozenBounds.remove();
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001267 if (!mFrozenMergedConfig.isEmpty()) {
1268 mFrozenMergedConfig.remove();
1269 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001270 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001271 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001272 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +01001273 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001274 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001275 }
1276
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001277 void setAppLayoutChanges(int changes, String reason) {
1278 if (!mChildren.isEmpty()) {
1279 final DisplayContent dc = getDisplayContent();
1280 dc.pendingLayoutChanges |= changes;
1281 if (DEBUG_LAYOUT_REPEATS) {
1282 mService.mWindowPlacerLocked.debugLayoutRepeats(reason, dc.pendingLayoutChanges);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001283 }
1284 }
1285 }
1286
1287 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001288 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001289 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001290 if (win.removeReplacedWindowIfNeeded(replacement)) {
1291 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001292 }
1293 }
1294 }
1295
1296 void startFreezingScreen() {
1297 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001298 + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001299 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001300 if (!hiddenRequested) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001301 if (!mFreezingScreen) {
1302 mFreezingScreen = true;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001303 mService.registerAppFreezeListener(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001304 mService.mAppsFreezingScreen++;
1305 if (mService.mAppsFreezingScreen == 1) {
Robert Carrae606b42018-02-15 15:36:23 -08001306 mService.startFreezingDisplayLocked(0, 0, getDisplayContent());
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001307 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1308 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001309 }
1310 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001311 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001312 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001313 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001314 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001315 }
1316 }
1317 }
1318
1319 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001320 if (!mFreezingScreen) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001321 return;
1322 }
1323 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001324 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001325 boolean unfrozeWindows = false;
1326 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001327 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001328 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001329 }
1330 if (force || unfrozeWindows) {
1331 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001332 mFreezingScreen = false;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001333 mService.unregisterAppFreezeListener(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001334 mService.mAppsFreezingScreen--;
1335 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001336 }
1337 if (unfreezeSurfaceNow) {
1338 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001339 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001340 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001341 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001342 }
1343 }
1344
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001345 @Override
1346 public void onAppFreezeTimeout() {
1347 Slog.w(TAG_WM, "Force clearing freeze: " + this);
1348 stopFreezingScreen(true, true);
1349 }
1350
Jorim Jaggi60f9c972018-02-01 19:21:07 +01001351 /**
1352 * Tries to transfer the starting window from a token that's above ourselves in the task but
1353 * not visible anymore. This is a common scenario apps use: Trampoline activity T start main
1354 * activity M in the same task. Now, when reopening the task, T starts on top of M but then
1355 * immediately finishes after, so we have to transfer T to M.
1356 */
1357 void transferStartingWindowFromHiddenAboveTokenIfNeeded() {
1358 final Task task = getTask();
1359 for (int i = task.mChildren.size() - 1; i >= 0; i--) {
1360 final AppWindowToken fromToken = task.mChildren.get(i);
1361 if (fromToken == this) {
1362 return;
1363 }
1364 if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) {
1365 return;
1366 }
1367 }
1368 }
1369
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001370 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001371 final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001372 if (fromToken == null) {
1373 return false;
1374 }
1375
1376 final WindowState tStartingWindow = fromToken.startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001377 if (tStartingWindow != null && fromToken.startingSurface != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001378 // In this case, the starting icon has already been displayed, so start
1379 // letting windows get shown immediately without any more transitions.
lumark588a3e82018-07-20 18:53:54 +08001380 getDisplayContent().mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001381
1382 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1383 + " from " + fromToken + " to " + this);
1384
1385 final long origId = Binder.clearCallingIdentity();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001386 try {
1387 // Transfer the starting window over to the new token.
1388 startingData = fromToken.startingData;
1389 startingSurface = fromToken.startingSurface;
1390 startingDisplayed = fromToken.startingDisplayed;
1391 fromToken.startingDisplayed = false;
1392 startingWindow = tStartingWindow;
1393 reportedVisible = fromToken.reportedVisible;
1394 fromToken.startingData = null;
1395 fromToken.startingSurface = null;
1396 fromToken.startingWindow = null;
1397 fromToken.startingMoved = true;
1398 tStartingWindow.mToken = this;
1399 tStartingWindow.mAppToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001400
Peter Visontay3556a3b2017-11-01 17:23:17 +00001401 if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1402 "Removing starting " + tStartingWindow + " from " + fromToken);
1403 fromToken.removeChild(tStartingWindow);
1404 fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
1405 fromToken.mHiddenSetFromTransferredStartingWindow = false;
1406 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001407
Peter Visontay3556a3b2017-11-01 17:23:17 +00001408 // Propagate other interesting state between the tokens. If the old token is displayed,
1409 // we should immediately force the new one to be displayed. If it is animating, we need
1410 // to move that animation to the new one.
1411 if (fromToken.allDrawn) {
1412 allDrawn = true;
1413 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1414 }
1415 if (fromToken.firstWindowDrawn) {
1416 firstWindowDrawn = true;
1417 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001418 if (!fromToken.isHidden()) {
1419 setHidden(false);
Peter Visontay3556a3b2017-11-01 17:23:17 +00001420 hiddenRequested = false;
1421 mHiddenSetFromTransferredStartingWindow = true;
1422 }
1423 setClientHidden(fromToken.mClientHidden);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001424
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001425 transferAnimation(fromToken);
1426
1427 // When transferring an animation, we no longer need to apply an animation to the
1428 // the token we transfer the animation over. Thus, remove the animation from
1429 // pending opening apps.
lumark588a3e82018-07-20 18:53:54 +08001430 getDisplayContent().mOpeningApps.remove(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001431
Peter Visontay3556a3b2017-11-01 17:23:17 +00001432 mService.updateFocusedWindowLocked(
1433 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
1434 getDisplayContent().setLayoutNeeded();
1435 mService.mWindowPlacerLocked.performSurfacePlacement();
1436 } finally {
1437 Binder.restoreCallingIdentity(origId);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001438 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001439 return true;
1440 } else if (fromToken.startingData != null) {
1441 // The previous app was getting ready to show a
1442 // starting window, but hasn't yet done so. Steal it!
1443 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1444 "Moving pending starting from " + fromToken + " to " + this);
1445 startingData = fromToken.startingData;
1446 fromToken.startingData = null;
1447 fromToken.startingMoved = true;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001448 scheduleAddStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001449 return true;
1450 }
1451
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001452 // TODO: Transfer thumbnail
1453
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001454 return false;
1455 }
1456
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001457 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001458 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001459 }
1460
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001461 @Override
1462 void onAppTransitionDone() {
1463 sendingToBottom = false;
1464 }
1465
Wale Ogunwale51362492016-09-08 17:49:17 -07001466 /**
1467 * We override because this class doesn't want its children affecting its reported orientation
1468 * in anyway.
1469 */
1470 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001471 int getOrientation(int candidate) {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001472 if (candidate == SCREEN_ORIENTATION_BEHIND) {
1473 // Allow app to specify orientation regardless of its visibility state if the current
1474 // candidate want us to use orientation behind. I.e. the visible app on-top of this one
1475 // wants us to use the orientation of the app behind it.
1476 return mOrientation;
1477 }
1478
Bryce Lee61fbcbc2017-03-10 14:14:03 -08001479 // The {@link AppWindowToken} should only specify an orientation when it is not closing or
1480 // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
1481 // an Activity in another task being started in the wrong orientation during the transition.
lumark588a3e82018-07-20 18:53:54 +08001482 if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
1483 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
Bryce Leea163b762017-01-24 11:05:01 -08001484 return mOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07001485 }
Bryce Leea163b762017-01-24 11:05:01 -08001486
1487 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001488 }
1489
Wale Ogunwaleb198b742016-12-01 08:44:09 -08001490 /** Returns the app's preferred orientation regardless of its currently visibility state. */
1491 int getOrientationIgnoreVisibility() {
1492 return mOrientation;
1493 }
1494
Craig Mautnerdbb79912012-03-01 18:59:14 -08001495 @Override
Winson Chunge55c0192017-08-24 14:50:48 -07001496 public void onConfigurationChanged(Configuration newParentConfig) {
1497 final int prevWinMode = getWindowingMode();
1498 super.onConfigurationChanged(newParentConfig);
1499 final int winMode = getWindowingMode();
1500
1501 if (prevWinMode == winMode) {
1502 return;
1503 }
1504
1505 if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) {
1506 // Entering PiP from fullscreen, reset the snap fraction
1507 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
Winson Chung82267ce2018-04-06 16:38:26 -07001508 } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED
1509 && !isHidden()) {
Winson Chunge55c0192017-08-24 14:50:48 -07001510 // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
1511 // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
1512 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
1513 if (pinnedStack != null) {
Winson Chung8efa1652018-06-06 09:34:23 -07001514 final Rect stackBounds;
1515 if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
1516 // We are animating the bounds, use the pre-animation bounds to save the snap
1517 // fraction
1518 stackBounds = pinnedStack.mPreAnimationBounds;
1519 } else {
1520 // We skip the animation if the fullscreen configuration is not compatible, so
1521 // use the current bounds to calculate the saved snap fraction instead
1522 // (see PinnedActivityStack.skipResizeAnimation())
1523 stackBounds = mTmpRect;
1524 pinnedStack.getBounds(stackBounds);
1525 }
Winson Chunge55c0192017-08-24 14:50:48 -07001526 mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
Winson Chung8efa1652018-06-06 09:34:23 -07001527 stackBounds);
Winson Chunge55c0192017-08-24 14:50:48 -07001528 }
1529 }
1530 }
1531
1532 @Override
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001533 void checkAppWindowsReadyToShow() {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001534 if (allDrawn == mLastAllDrawn) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001535 return;
1536 }
1537
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001538 mLastAllDrawn = allDrawn;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001539 if (!allDrawn) {
1540 return;
1541 }
1542
1543 // The token has now changed state to having all windows shown... what to do, what to do?
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001544 if (mFreezingScreen) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001545 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001546 stopFreezingScreen(false, true);
1547 if (DEBUG_ORIENTATION) Slog.i(TAG,
1548 "Setting mOrientationChangeComplete=true because wtoken " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001549 + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001550 // This will set mOrientationChangeComplete and cause a pass through layout.
1551 setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001552 "checkAppWindowsReadyToShow: freezingScreen");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001553 } else {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001554 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001555
1556 // We can now show all of the drawn windows!
lumark588a3e82018-07-20 18:53:54 +08001557 if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001558 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001559 }
1560 }
1561 }
1562
Matthew Ng5d23afa2017-06-21 16:16:24 -07001563 /**
Bryce Leed390deb2017-06-22 13:14:28 -07001564 * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
1565 * child {@link WindowState}. A child is considered if it has been passed into
1566 * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
1567 * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
1568 * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
1569 *
1570 * @return {@code true} If all children have been considered, {@code false}.
1571 */
1572 private boolean allDrawnStatesConsidered() {
Bryce Lee6311c4b2017-07-06 14:09:29 -07001573 for (int i = mChildren.size() - 1; i >= 0; --i) {
1574 final WindowState child = mChildren.get(i);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001575 if (child.mightAffectAllDrawn() && !child.getDrawnStateEvaluated()) {
Bryce Leed390deb2017-06-22 13:14:28 -07001576 return false;
1577 }
1578 }
1579 return true;
1580 }
1581
1582 /**
Matthew Ng5d23afa2017-06-21 16:16:24 -07001583 * Determines if the token has finished drawing. This should only be called from
1584 * {@link DisplayContent#applySurfaceChangesTransaction}
1585 */
Matthew Ng498c71d2017-04-18 13:55:45 -07001586 void updateAllDrawn() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001587 if (!allDrawn) {
Matthew Ng498c71d2017-04-18 13:55:45 -07001588 // Number of drawn windows can be less when a window is being relaunched, wait for
Bryce Leed390deb2017-06-22 13:14:28 -07001589 // all windows to be launched and drawn for this token be considered all drawn.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001590 final int numInteresting = mNumInterestingWindows;
Bryce Leed390deb2017-06-22 13:14:28 -07001591
1592 // We must make sure that all present children have been considered (determined by
1593 // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
1594 // drawn.
1595 if (numInteresting > 0 && allDrawnStatesConsidered()
1596 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001597 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001598 + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001599 allDrawn = true;
1600 // Force an additional layout pass where
1601 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
Matthew Ng498c71d2017-04-18 13:55:45 -07001602 if (mDisplayContent != null) {
1603 mDisplayContent.setLayoutNeeded();
1604 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001605 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Robert Carrecc06b32017-04-18 14:25:10 -07001606
Winson Chunge7ba6862017-05-24 12:13:33 -07001607 // Notify the pinned stack upon all windows drawn. If there was an animation in
1608 // progress then this signal will resume that animation.
Wale Ogunwale61911492017-10-11 08:50:50 -07001609 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
Winson Chunge7ba6862017-05-24 12:13:33 -07001610 if (pinnedStack != null) {
1611 pinnedStack.onAllWindowsDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -07001612 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001613 }
1614 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001615 }
1616
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001617 boolean keyDispatchingTimedOut(String reason, int windowPid) {
1618 return mActivityRecord != null && mActivityRecord.keyDispatchingTimedOut(reason, windowPid);
1619 }
1620
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001621 /**
1622 * Updated this app token tracking states for interesting and drawn windows based on the window.
1623 *
1624 * @return Returns true if the input window is considered interesting and drawn while all the
1625 * windows in this app token where not considered drawn as of the last pass.
1626 */
1627 boolean updateDrawnWindowStates(WindowState w) {
Bryce Leed390deb2017-06-22 13:14:28 -07001628 w.setDrawnStateEvaluated(true /*evaluated*/);
1629
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001630 if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001631 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001632 + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001633 }
1634
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001635 if (allDrawn && !mFreezingScreen) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001636 return false;
1637 }
1638
1639 if (mLastTransactionSequence != mService.mTransactionSequence) {
1640 mLastTransactionSequence = mService.mTransactionSequence;
Matthew Ng53e66b22018-01-12 17:13:13 -08001641 mNumDrawnWindows = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001642 startingDisplayed = false;
Matthew Ng53e66b22018-01-12 17:13:13 -08001643
1644 // There is the main base application window, even if it is exiting, wait for it
1645 mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001646 }
1647
1648 final WindowStateAnimator winAnimator = w.mWinAnimator;
1649
1650 boolean isInterestingAndDrawn = false;
1651
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001652 if (!allDrawn && w.mightAffectAllDrawn()) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001653 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1654 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001655 + ", isAnimationSet=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001656 if (!w.isDrawnLw()) {
1657 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
1658 + " pv=" + w.mPolicyVisibility
1659 + " mDrawState=" + winAnimator.drawStateToString()
1660 + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001661 + " a=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001662 }
1663 }
1664
1665 if (w != startingWindow) {
1666 if (w.isInteresting()) {
Matthew Ng53e66b22018-01-12 17:13:13 -08001667 // Add non-main window as interesting since the main app has already been added
1668 if (findMainWindow(false /* includeStartingApp */) != w) {
1669 mNumInterestingWindows++;
1670 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001671 if (w.isDrawnLw()) {
1672 mNumDrawnWindows++;
1673
1674 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
1675 + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001676 + " freezingScreen=" + mFreezingScreen
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001677 + " mAppFreezing=" + w.mAppFreezing);
1678
1679 isInterestingAndDrawn = true;
1680 }
1681 }
1682 } else if (w.isDrawnLw()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001683 if (mActivityRecord != null) {
1684 mActivityRecord.onStartingWindowDrawn(SystemClock.uptimeMillis());
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001685 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001686 startingDisplayed = true;
1687 }
1688 }
1689
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001690 return isInterestingAndDrawn;
1691 }
1692
Adrian Roos23df3a32018-03-15 15:41:13 +01001693 void layoutLetterbox(WindowState winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001694 final WindowState w = findMainWindow();
Adrian Roosf93b6d22018-03-21 13:48:26 +01001695 if (w == null || winHint != null && w != winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001696 return;
1697 }
Jorim Jaggia32da382018-03-28 18:01:22 +02001698 final boolean surfaceReady = w.isDrawnLw() // Regular case
Adrian Roosf93b6d22018-03-21 13:48:26 +01001699 || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
1700 || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
1701 final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001702 if (needsLetterbox) {
1703 if (mLetterbox == null) {
1704 mLetterbox = new Letterbox(() -> makeChildSurface(null));
1705 }
chaviw492139a2018-07-16 16:07:35 -07001706 mLetterbox.layout(getParent().getBounds(), w.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001707 } else if (mLetterbox != null) {
Adrian Roos23df3a32018-03-15 15:41:13 +01001708 mLetterbox.hide();
1709 }
1710 }
1711
1712 void updateLetterboxSurface(WindowState winHint) {
1713 final WindowState w = findMainWindow();
1714 if (w != winHint && winHint != null && w != null) {
1715 return;
1716 }
1717 layoutLetterbox(winHint);
1718 if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
1719 mLetterbox.applySurfaceChanges(mPendingTransaction);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001720 }
1721 }
1722
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001723 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001724 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001725 // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
1726 // before the non-exiting app tokens. So, we skip the exiting app tokens here.
1727 // TODO: Investigate if we need to continue to do this or if we can just process them
1728 // in-order.
1729 if (mIsExiting && !waitingForReplacement()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001730 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001731 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001732 return forAllWindowsUnchecked(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001733 }
1734
lumark588a3e82018-07-20 18:53:54 +08001735 @Override
1736 void forAllAppWindows(Consumer<AppWindowToken> callback) {
1737 callback.accept(this);
1738 }
1739
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001740 boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
1741 boolean traverseTopToBottom) {
1742 return super.forAllWindows(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001743 }
1744
1745 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001746 AppWindowToken asAppWindowToken() {
1747 // I am an app window token!
1748 return this;
1749 }
1750
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001751 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1752 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1753 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1754 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1755 // If the display is frozen, we won't do anything until the actual window is
1756 // displayed so there is no reason to put in the starting window.
1757 if (!okToDisplay()) {
1758 return false;
1759 }
1760
1761 if (startingData != null) {
1762 return false;
1763 }
1764
1765 final WindowState mainWin = findMainWindow();
1766 if (mainWin != null && mainWin.mWinAnimator.getShown()) {
1767 // App already has a visible window...why would you want a starting window?
1768 return false;
1769 }
1770
1771 final ActivityManager.TaskSnapshot snapshot =
1772 mService.mTaskSnapshotController.getSnapshot(
1773 getTask().mTaskId, getTask().mUserId,
1774 false /* restoreFromDisk */, false /* reducedResolution */);
1775 final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
1776 allowTaskSnapshot, activityCreated, fromRecents, snapshot);
1777
1778 if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
1779 return createSnapshot(snapshot);
1780 }
1781
1782 // If this is a translucent window, then don't show a starting window -- the current
1783 // effect (a full-screen opaque starting window that fades away to the real contents
1784 // when it is ready) does not work for this.
1785 if (DEBUG_STARTING_WINDOW) {
1786 Slog.v(TAG, "Checking theme of starting window: 0x" + Integer.toHexString(theme));
1787 }
1788 if (theme != 0) {
1789 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
1790 com.android.internal.R.styleable.Window,
1791 mService.mCurrentUserId);
1792 if (ent == null) {
1793 // Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
1794 // see that.
1795 return false;
1796 }
1797 final boolean windowIsTranslucent = ent.array.getBoolean(
1798 com.android.internal.R.styleable.Window_windowIsTranslucent, false);
1799 final boolean windowIsFloating = ent.array.getBoolean(
1800 com.android.internal.R.styleable.Window_windowIsFloating, false);
1801 final boolean windowShowWallpaper = ent.array.getBoolean(
1802 com.android.internal.R.styleable.Window_windowShowWallpaper, false);
1803 final boolean windowDisableStarting = ent.array.getBoolean(
1804 com.android.internal.R.styleable.Window_windowDisablePreview, false);
1805 if (DEBUG_STARTING_WINDOW) {
1806 Slog.v(TAG, "Translucent=" + windowIsTranslucent
1807 + " Floating=" + windowIsFloating
1808 + " ShowWallpaper=" + windowShowWallpaper);
1809 }
1810 if (windowIsTranslucent) {
1811 return false;
1812 }
1813 if (windowIsFloating || windowDisableStarting) {
1814 return false;
1815 }
1816 if (windowShowWallpaper) {
1817 if (getDisplayContent().mWallpaperController
1818 .getWallpaperTarget() == null) {
1819 // If this theme is requesting a wallpaper, and the wallpaper
1820 // is not currently visible, then this effectively serves as
1821 // an opaque window and our starting window transition animation
1822 // can still work. We just need to make sure the starting window
1823 // is also showing the wallpaper.
1824 windowFlags |= FLAG_SHOW_WALLPAPER;
1825 } else {
1826 return false;
1827 }
1828 }
1829
1830 if (transferStartingWindow(transferFrom)) {
1831 return true;
1832 }
1833
1834 // There is no existing starting window, and we don't want to create a splash screen, so
1835 // that's it!
1836 if (type != STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
1837 return false;
1838 }
1839
1840 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
1841 startingData = new SplashScreenStartingData(mService, pkg,
1842 theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
1843 getMergedOverrideConfiguration());
1844 scheduleAddStartingWindow();
1845 }
1846 return true;
1847 }
1848
1849
1850 private boolean createSnapshot(ActivityManager.TaskSnapshot snapshot) {
1851 if (snapshot == null) {
1852 return false;
1853 }
1854
1855 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
1856 startingData = new SnapshotStartingData(mService, snapshot);
1857 scheduleAddStartingWindow();
1858 return true;
1859 }
1860
1861 void scheduleAddStartingWindow() {
1862 // Note: we really want to do sendMessageAtFrontOfQueue() because we
1863 // want to process the message ASAP, before any other queued
1864 // messages.
1865 if (!mService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
1866 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
1867 mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
1868 }
1869 }
1870
1871 private final Runnable mAddStartingWindow = new Runnable() {
1872
1873 @Override
1874 public void run() {
1875 synchronized (mService.mGlobalLock) {
1876 // There can only be one adding request, silly caller!
1877 mService.mAnimationHandler.removeCallbacks(this);
1878 }
1879
1880 if (startingData == null) {
1881 // Animation has been canceled... do nothing.
1882 if (DEBUG_STARTING_WINDOW) {
1883 Slog.v(TAG, "startingData was nulled out before handling"
1884 + " mAddStartingWindow: " + AppWindowToken.this);
1885 }
1886 return;
1887 }
1888
1889 if (DEBUG_STARTING_WINDOW) {
1890 Slog.v(TAG, "Add starting " + this + ": startingData=" + startingData);
1891 }
1892
1893 WindowManagerPolicy.StartingSurface surface = null;
1894 try {
1895 surface = startingData.createStartingSurface(AppWindowToken.this);
1896 } catch (Exception e) {
1897 Slog.w(TAG, "Exception when adding starting window", e);
1898 }
1899 if (surface != null) {
1900 boolean abort = false;
1901 synchronized (mService.mGlobalLock) {
1902 // If the window was successfully added, then
1903 // we need to remove it.
1904 if (removed || startingData == null) {
1905 if (DEBUG_STARTING_WINDOW) {
1906 Slog.v(TAG, "Aborted starting " + AppWindowToken.this
1907 + ": removed=" + removed + " startingData=" + startingData);
1908 }
1909 startingWindow = null;
1910 startingData = null;
1911 abort = true;
1912 } else {
1913 startingSurface = surface;
1914 }
1915 if (DEBUG_STARTING_WINDOW && !abort) {
1916 Slog.v(TAG, "Added starting " + AppWindowToken.this + ": startingWindow="
1917 + startingWindow + " startingView=" + startingSurface);
1918 }
1919 }
1920 if (abort) {
1921 surface.remove();
1922 }
1923 } else if (DEBUG_STARTING_WINDOW) {
1924 Slog.v(TAG, "Surface returned was null: " + AppWindowToken.this);
1925 }
1926 }
1927 };
1928
1929 private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
1930 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
1931 ActivityManager.TaskSnapshot snapshot) {
1932 if (getDisplayContent().mAppTransition.getAppTransition()
1933 == TRANSIT_DOCK_TASK_FROM_RECENTS) {
1934 // TODO(b/34099271): Remove this statement to add back the starting window and figure
1935 // out why it causes flickering, the starting window appears over the thumbnail while
1936 // the docked from recents transition occurs
1937 return STARTING_WINDOW_TYPE_NONE;
1938 } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
1939 return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1940 } else if (taskSwitch && allowTaskSnapshot) {
1941 return snapshot == null ? STARTING_WINDOW_TYPE_NONE
1942 : snapshotOrientationSameAsTask(snapshot) || fromRecents
1943 ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1944 } else {
1945 return STARTING_WINDOW_TYPE_NONE;
1946 }
1947 }
1948
1949
1950 private boolean snapshotOrientationSameAsTask(ActivityManager.TaskSnapshot snapshot) {
1951 if (snapshot == null) {
1952 return false;
1953 }
1954 return getTask().getConfiguration().orientation == snapshot.getOrientation();
1955 }
1956
1957 void removeStartingWindow() {
1958 if (startingWindow == null) {
1959 if (startingData != null) {
1960 // Starting window has not been added yet, but it is scheduled to be added.
1961 // Go ahead and cancel the request.
1962 if (DEBUG_STARTING_WINDOW) {
1963 Slog.v(TAG_WM, "Clearing startingData for token=" + this);
1964 }
1965 startingData = null;
1966 }
1967 return;
1968 }
1969
1970 final WindowManagerPolicy.StartingSurface surface;
1971 if (startingData != null) {
1972 surface = startingSurface;
1973 startingData = null;
1974 startingSurface = null;
1975 startingWindow = null;
1976 startingDisplayed = false;
1977 if (surface == null) {
1978 if (DEBUG_STARTING_WINDOW) {
1979 Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
1980 + "remove");
1981 }
1982 return;
1983 }
1984 } else {
1985 if (DEBUG_STARTING_WINDOW) {
1986 Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
1987 + this);
1988 }
1989 return;
1990 }
1991
1992 if (DEBUG_STARTING_WINDOW) {
1993 Slog.v(TAG_WM, "Schedule remove starting " + this
1994 + " startingWindow=" + startingWindow
1995 + " startingView=" + startingSurface
1996 + " Callers=" + Debug.getCallers(5));
1997 }
1998
1999 // Use the same thread to remove the window as we used to add it, as otherwise we end up
2000 // with things in the view hierarchy being called from different threads.
2001 mService.mAnimationHandler.post(() -> {
2002 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
2003 try {
2004 surface.remove();
2005 } catch (Exception e) {
2006 Slog.w(TAG_WM, "Exception when removing starting window", e);
2007 }
2008 });
2009 }
2010
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07002011 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07002012 boolean fillsParent() {
2013 return mFillsParent;
2014 }
2015
2016 void setFillsParent(boolean fillsParent) {
2017 mFillsParent = fillsParent;
2018 }
2019
Jorim Jaggife762342016-10-13 14:33:27 +02002020 boolean containsDismissKeyguardWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002021 // Window state is transient during relaunch. We are not guaranteed to be frozen during the
2022 // entirety of the relaunch.
2023 if (isRelaunching()) {
2024 return mLastContainsDismissKeyguardWindow;
2025 }
2026
Jorim Jaggife762342016-10-13 14:33:27 +02002027 for (int i = mChildren.size() - 1; i >= 0; i--) {
2028 if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
2029 return true;
2030 }
2031 }
2032 return false;
2033 }
2034
2035 boolean containsShowWhenLockedWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002036 // When we are relaunching, it is possible for us to be unfrozen before our previous
2037 // windows have been added back. Using the cached value ensures that our previous
2038 // showWhenLocked preference is honored until relaunching is complete.
2039 if (isRelaunching()) {
2040 return mLastContainsShowWhenLockedWindow;
2041 }
2042
Jorim Jaggife762342016-10-13 14:33:27 +02002043 for (int i = mChildren.size() - 1; i >= 0; i--) {
2044 if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
2045 return true;
2046 }
2047 }
Bryce Lee081554b2017-05-25 07:52:12 -07002048
Jorim Jaggife762342016-10-13 14:33:27 +02002049 return false;
2050 }
2051
2052 void checkKeyguardFlagsChanged() {
2053 final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
2054 final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
2055 if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
2056 || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
lumark588a3e82018-07-20 18:53:54 +08002057 mService.notifyKeyguardFlagsChanged(null /* callback */,
2058 getDisplayContent().getDisplayId());
Jorim Jaggife762342016-10-13 14:33:27 +02002059 }
2060 mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
2061 mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
2062 }
2063
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002064 WindowState getImeTargetBelowWindow(WindowState w) {
2065 final int index = mChildren.indexOf(w);
2066 if (index > 0) {
2067 final WindowState target = mChildren.get(index - 1);
2068 if (target.canBeImeTarget()) {
2069 return target;
2070 }
2071 }
2072 return null;
2073 }
2074
2075 WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
2076 WindowState candidate = null;
2077 for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
2078 final WindowState w = mChildren.get(i);
2079 if (w.mRemoved) {
2080 continue;
2081 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02002082 if (candidate == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002083 candidate = w;
2084 }
2085 }
2086 return candidate;
2087 }
2088
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002089 /**
2090 * See {@link Activity#setDisablePreviewScreenshots}.
2091 */
2092 void setDisablePreviewScreenshots(boolean disable) {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002093 mDisablePreviewScreenshots = disable;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002094 }
2095
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002096 /**
chaviwd3bf08d2017-08-01 17:24:59 -07002097 * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
2098 */
2099 void setCanTurnScreenOn(boolean canTurnScreenOn) {
2100 mCanTurnScreenOn = canTurnScreenOn;
2101 }
2102
2103 /**
2104 * Indicates whether the current launch can turn the screen on. This is to prevent multiple
2105 * relayouts from turning the screen back on. The screen should only turn on at most
2106 * once per activity resume.
2107 *
2108 * @return true if the screen can be turned on.
2109 */
2110 boolean canTurnScreenOn() {
2111 return mCanTurnScreenOn;
2112 }
2113
2114 /**
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002115 * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
2116 * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
2117 * we can't take a snapshot for other reasons, for example, if we have a secure window.
2118 *
2119 * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
2120 * screenshot.
2121 */
2122 boolean shouldUseAppThemeSnapshot() {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002123 return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002124 true /* topToBottom */);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002125 }
2126
Jorim Jaggibe418292018-03-26 16:14:12 +02002127 SurfaceControl getAppAnimationLayer() {
Jorim Jaggi391790622018-04-18 15:30:44 +02002128 return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
2129 : needsZBoost() ? ANIMATION_LAYER_BOOSTED
2130 : ANIMATION_LAYER_STANDARD);
Jorim Jaggibe418292018-03-26 16:14:12 +02002131 }
2132
chaviw23ee71c2017-12-18 11:29:41 -08002133 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +01002134 public SurfaceControl getAnimationLeashParent() {
Robert Carrb9506032018-02-13 13:54:00 -08002135 // All normal app transitions take place in an animation layer which is below the pinned
2136 // stack but may be above the parent stacks of the given animating apps.
2137 // For transitions in the pinned stack (menu activity) we just let them occur as a child
2138 // of the pinned stack.
2139 if (!inPinnedWindowingMode()) {
2140 return getAppAnimationLayer();
2141 } else {
2142 return getStack().getSurfaceControl();
2143 }
chaviw23ee71c2017-12-18 11:29:41 -08002144 }
2145
Jorim Jaggic6976f02018-04-18 16:31:07 +02002146 private boolean shouldAnimate(int transit) {
2147 final boolean isSplitScreenPrimary =
2148 getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
2149 final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
2150
2151 // We animate always if it's not split screen primary, and only some special cases in split
2152 // screen primary because it causes issues with stack clipping when we run an un-minimize
2153 // animation at the same time.
2154 return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
2155 }
2156
Vishnu Naira2977262018-07-26 13:31:26 -07002157 /**
2158 * Creates a layer to apply crop to an animation.
2159 */
2160 private SurfaceControl createAnimationBoundsLayer(Transaction t) {
2161 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
2162 final SurfaceControl.Builder builder = makeAnimationLeash()
2163 .setParent(getAnimationLeashParent())
Vishnu Naire86bd982018-11-28 13:23:17 -08002164 .setName(getSurfaceControl() + " - animation-bounds");
Vishnu Naira2977262018-07-26 13:31:26 -07002165 final SurfaceControl boundsLayer = builder.build();
2166 t.show(boundsLayer);
2167 return boundsLayer;
2168 }
2169
Riddle Hsua118b3a2018-10-11 22:05:06 +08002170 /** Get position and crop region of animation. */
2171 @VisibleForTesting
2172 void getAnimationBounds(Point outPosition, Rect outBounds) {
2173 outPosition.set(0, 0);
2174 outBounds.setEmpty();
2175
2176 final TaskStack stack = getStack();
2177 final Task task = getTask();
2178 if (task != null && task.inFreeformWindowingMode()) {
2179 task.getRelativePosition(outPosition);
2180 } else if (stack != null) {
2181 stack.getRelativePosition(outPosition);
2182 }
2183
2184 // Always use stack bounds in order to have the ability to animate outside the task region.
2185 // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
2186 // according to the bounds.
2187 if (stack != null) {
2188 stack.getBounds(outBounds);
2189 }
2190 // We have the relative position so the local position can be removed from bounds.
2191 outBounds.offsetTo(0, 0);
2192 }
2193
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002194 boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
2195 boolean isVoiceInteraction) {
2196
Jorim Jaggic6976f02018-04-18 16:31:07 +02002197 if (mService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002198 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Jorim Jaggic6976f02018-04-18 16:31:07 +02002199 Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
2200 + " atoken=" + this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002201 }
2202 cancelAnimation();
2203 return false;
2204 }
2205
2206 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
2207 // to animate and it can cause strange artifacts when we unfreeze the display if some
2208 // different animation is running.
2209 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
2210 if (okToAnimate()) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002211 final AnimationAdapter adapter;
Riddle Hsua118b3a2018-10-11 22:05:06 +08002212 getAnimationBounds(mTmpPoint, mTmpRect);
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002213
2214 // Delaying animation start isn't compatible with remote animations at all.
lumark588a3e82018-07-20 18:53:54 +08002215 if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002216 && !mSurfaceAnimator.isAnimationStartDelayed()) {
lumark588a3e82018-07-20 18:53:54 +08002217 adapter = getDisplayContent().mAppTransition.getRemoteAnimationController()
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002218 .createAnimationAdapter(this, mTmpPoint, mTmpRect);
2219 } else {
lumark588a3e82018-07-20 18:53:54 +08002220 final int appStackClipMode =
2221 getDisplayContent().mAppTransition.getAppStackClipMode();
Vishnu Naira2977262018-07-26 13:31:26 -07002222 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
2223
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002224 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
2225 if (a != null) {
2226 adapter = new LocalAnimationAdapter(
2227 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
lumark588a3e82018-07-20 18:53:54 +08002228 getDisplayContent().mAppTransition.canSkipFirstFrame(),
Vishnu Naira2977262018-07-26 13:31:26 -07002229 appStackClipMode,
Jorim Jaggiaa763cd2018-03-22 23:20:36 +01002230 true /* isAppAnimation */),
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002231 mService.mSurfaceAnimationRunner);
2232 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
2233 mNeedsZBoost = true;
2234 }
2235 mTransit = transit;
lumark588a3e82018-07-20 18:53:54 +08002236 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002237 } else {
2238 adapter = null;
chaviw23ee71c2017-12-18 11:29:41 -08002239 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002240 }
2241 if (adapter != null) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002242 startAnimation(getPendingTransaction(), adapter, !isVisible());
Jorim Jaggi82c17862018-02-21 17:50:18 +01002243 if (adapter.getShowWallpaper()) {
2244 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2245 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002246 }
2247 } else {
2248 cancelAnimation();
2249 }
2250 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2251
2252 return isReallyAnimating();
2253 }
2254
2255 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
2256 boolean isVoiceInteraction) {
2257 final DisplayContent displayContent = getTask().getDisplayContent();
2258 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2259 final int width = displayInfo.appWidth;
2260 final int height = displayInfo.appHeight;
2261 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
2262 "applyAnimation: atoken=" + this);
2263
2264 // Determine the visible rect to calculate the thumbnail clip
2265 final WindowState win = findMainWindow();
2266 final Rect frame = new Rect(0, 0, width, height);
2267 final Rect displayFrame = new Rect(0, 0,
2268 displayInfo.logicalWidth, displayInfo.logicalHeight);
2269 final Rect insets = new Rect();
2270 final Rect stableInsets = new Rect();
2271 Rect surfaceInsets = null;
2272 final boolean freeform = win != null && win.inFreeformWindowingMode();
2273 if (win != null) {
2274 // Containing frame will usually cover the whole screen, including dialog windows.
2275 // For freeform workspace windows it will not cover the whole screen and it also
2276 // won't exactly match the final freeform window frame (e.g. when overlapping with
2277 // the status bar). In that case we need to use the final frame.
2278 if (freeform) {
chaviw492139a2018-07-16 16:07:35 -07002279 frame.set(win.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01002280 } else if (win.isLetterboxedAppWindow()) {
2281 frame.set(getTask().getBounds());
Winson Chungc1674272018-02-21 10:15:17 -08002282 } else if (win.isDockedResizing()) {
2283 // If we are animating while docked resizing, then use the stack bounds as the
2284 // animation target (which will be different than the task bounds)
2285 frame.set(getTask().getParent().getBounds());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002286 } else {
chaviw553b0212018-07-12 13:37:01 -07002287 frame.set(win.getContainingFrame());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002288 }
2289 surfaceInsets = win.getAttrs().surfaceInsets;
Adrian Roos20e07892018-02-23 19:12:01 +01002290 // XXX(b/72757033): These are insets relative to the window frame, but we're really
2291 // interested in the insets relative to the frame we chose in the if-blocks above.
chaviw9c81e632018-07-31 11:17:52 -07002292 win.getContentInsets(insets);
2293 win.getStableInsets(stableInsets);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002294 }
2295
2296 if (mLaunchTaskBehind) {
2297 // Differentiate the two animations. This one which is briefly on the screen
2298 // gets the !enter animation, and the other activity which remains on the
2299 // screen gets the enter animation. Both appear in the mOpeningApps set.
2300 enter = false;
2301 }
2302 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
2303 + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
2304 + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
2305 final Configuration displayConfig = displayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002306 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002307 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
2308 surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
2309 if (a != null) {
2310 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
2311 final int containingWidth = frame.width();
2312 final int containingHeight = frame.height();
2313 a.initialize(containingWidth, containingHeight, width, height);
2314 a.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
2315 }
2316 return a;
2317 }
2318
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002319 @Override
Jorim Jaggi6de61012018-03-19 14:53:23 +01002320 public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
2321 return mAnimatingAppWindowTokenRegistry != null
2322 && mAnimatingAppWindowTokenRegistry.notifyAboutToFinish(
2323 this, endDeferFinishCallback);
2324 }
2325
2326 @Override
2327 public void onAnimationLeashDestroyed(Transaction t) {
2328 super.onAnimationLeashDestroyed(t);
Vishnu Naira2977262018-07-26 13:31:26 -07002329 if (mAnimationBoundsLayer != null) {
2330 t.destroy(mAnimationBoundsLayer);
2331 mAnimationBoundsLayer = null;
2332 }
2333
Jorim Jaggi6de61012018-03-19 14:53:23 +01002334 if (mAnimatingAppWindowTokenRegistry != null) {
2335 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
2336 }
2337 }
2338
2339 @Override
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002340 protected void setLayer(Transaction t, int layer) {
2341 if (!mSurfaceAnimator.hasLeash()) {
2342 t.setLayer(mSurfaceControl, layer);
2343 }
2344 }
2345
2346 @Override
2347 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
2348 if (!mSurfaceAnimator.hasLeash()) {
2349 t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
2350 }
2351 }
2352
2353 @Override
2354 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
2355 if (!mSurfaceAnimator.hasLeash()) {
2356 t.reparent(mSurfaceControl, newParent.getHandle());
2357 }
2358 }
2359
2360 @Override
2361 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002362 // The leash is parented to the animation layer. We need to preserve the z-order by using
2363 // the prefix order index, but we boost if necessary.
Robert Carrb9506032018-02-13 13:54:00 -08002364 int layer = 0;
2365 if (!inPinnedWindowingMode()) {
2366 layer = getPrefixOrderIndex();
2367 } else {
2368 // Pinned stacks have animations take place within themselves rather than an animation
2369 // layer so we need to preserve the order relative to the stack (e.g. the order of our
2370 // task/parent).
2371 layer = getParent().getPrefixOrderIndex();
2372 }
2373
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002374 if (mNeedsZBoost) {
2375 layer += Z_BOOST_BASE;
2376 }
2377 leash.setLayer(layer);
Robert Carr2f8aa392018-01-31 14:46:51 -08002378
2379 final DisplayContent dc = getDisplayContent();
Jorim Jaggibe418292018-03-26 16:14:12 +02002380 dc.assignStackOrdering();
Jorim Jaggi6de61012018-03-19 14:53:23 +01002381 if (mAnimatingAppWindowTokenRegistry != null) {
2382 mAnimatingAppWindowTokenRegistry.notifyStarting(this);
2383 }
Vishnu Naira2977262018-07-26 13:31:26 -07002384
2385 // If the animation needs to be cropped then an animation bounds layer is created as a child
2386 // of the pinned stack or animation layer. The leash is then reparented to this new layer.
2387 if (mNeedsAnimationBoundsLayer) {
2388 final TaskStack stack = getStack();
2389 if (stack == null) {
2390 return;
2391 }
2392 mAnimationBoundsLayer = createAnimationBoundsLayer(t);
2393
2394 // Set clip rect to stack bounds.
2395 mTmpRect.setEmpty();
2396 stack.getBounds(mTmpRect);
2397
2398 // Crop to stack bounds.
2399 t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
2400
2401 // Reparent leash to animation bounds layer.
2402 t.reparent(leash, mAnimationBoundsLayer.getHandle());
2403 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002404 }
2405
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002406 /**
2407 * This must be called while inside a transaction.
2408 */
2409 void showAllWindowsLocked() {
2410 forAllWindows(windowState -> {
2411 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + windowState);
2412 windowState.performShowLocked();
2413 }, false /* traverseTopToBottom */);
Jorim Jaggia5e10572017-11-15 14:36:26 +01002414 }
2415
2416 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002417 protected void onAnimationFinished() {
2418 super.onAnimationFinished();
2419
2420 mTransit = TRANSIT_UNSET;
2421 mTransitFlags = 0;
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002422 mNeedsZBoost = false;
Vishnu Naira2977262018-07-26 13:31:26 -07002423 mNeedsAnimationBoundsLayer = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002424
2425 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
2426 "AppWindowToken");
2427
Jorim Jaggi988f6682017-11-17 17:46:43 +01002428 clearThumbnail();
Jorim Jaggi752cd822018-03-29 16:29:18 +02002429 setClientHidden(isHidden() && hiddenRequested);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002430
lumarkff0ab692018-11-05 20:32:30 +08002431 getDisplayContent().computeImeTargetIfNeeded(this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002432
2433 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this
2434 + ": reportedVisible=" + reportedVisible
2435 + " okToDisplay=" + okToDisplay()
2436 + " okToAnimate=" + okToAnimate()
2437 + " startingDisplayed=" + startingDisplayed);
2438
2439 // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
2440 // traverse the copy.
2441 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
2442 children.forEach(WindowState::onExitAnimationDone);
2443
lumark588a3e82018-07-20 18:53:54 +08002444 getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002445 scheduleAnimation();
2446 }
2447
2448 @Override
2449 boolean isAppAnimating() {
2450 return isSelfAnimating();
2451 }
2452
2453 @Override
2454 boolean isSelfAnimating() {
2455 // If we are about to start a transition, we also need to be considered animating.
2456 return isWaitingForTransitionStart() || isReallyAnimating();
2457 }
2458
2459 /**
2460 * @return True if and only if we are actually running an animation. Note that
2461 * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
2462 * start.
2463 */
2464 private boolean isReallyAnimating() {
2465 return super.isSelfAnimating();
2466 }
2467
Jorim Jaggi988f6682017-11-17 17:46:43 +01002468 @Override
2469 void cancelAnimation() {
2470 super.cancelAnimation();
2471 clearThumbnail();
2472 }
2473
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002474 boolean isWaitingForTransitionStart() {
lumark588a3e82018-07-20 18:53:54 +08002475 return getDisplayContent().mAppTransition.isTransitionSet()
2476 && (getDisplayContent().mOpeningApps.contains(this)
2477 || getDisplayContent().mClosingApps.contains(this));
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002478 }
2479
2480 public int getTransit() {
2481 return mTransit;
2482 }
2483
2484 int getTransitFlags() {
2485 return mTransitFlags;
2486 }
2487
Jorim Jaggi988f6682017-11-17 17:46:43 +01002488 void attachThumbnailAnimation() {
2489 if (!isReallyAnimating()) {
2490 return;
2491 }
2492 final int taskId = getTask().mTaskId;
2493 final GraphicBuffer thumbnailHeader =
lumark588a3e82018-07-20 18:53:54 +08002494 getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002495 if (thumbnailHeader == null) {
2496 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
2497 return;
2498 }
2499 clearThumbnail();
2500 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
2501 mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
2502 }
2503
Tony Mak64b8d562017-12-28 17:44:02 +00002504 /**
2505 * Attaches a surface with a thumbnail for the
2506 * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
2507 */
2508 void attachCrossProfileAppsThumbnailAnimation() {
2509 if (!isReallyAnimating()) {
2510 return;
2511 }
2512 clearThumbnail();
2513
2514 final WindowState win = findMainWindow();
2515 if (win == null) {
2516 return;
2517 }
chaviw492139a2018-07-16 16:07:35 -07002518 final Rect frame = win.getFrameLw();
Tony Mak64b8d562017-12-28 17:44:02 +00002519 final int thumbnailDrawableRes = getTask().mUserId == mService.mCurrentUserId
2520 ? R.drawable.ic_account_circle
Tony Makda4af232018-04-27 11:01:10 +01002521 : R.drawable.ic_corp_badge;
Tony Mak64b8d562017-12-28 17:44:02 +00002522 final GraphicBuffer thumbnail =
lumark588a3e82018-07-20 18:53:54 +08002523 getDisplayContent().mAppTransition
Tony Mak64b8d562017-12-28 17:44:02 +00002524 .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
2525 if (thumbnail == null) {
2526 return;
2527 }
2528 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
2529 final Animation animation =
lumark588a3e82018-07-20 18:53:54 +08002530 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
chaviw492139a2018-07-16 16:07:35 -07002531 win.getFrameLw());
Tony Mak64b8d562017-12-28 17:44:02 +00002532 mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
2533 frame.top));
2534 }
2535
Jorim Jaggi988f6682017-11-17 17:46:43 +01002536 private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
2537 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
2538
2539 // If this is a multi-window scenario, we use the windows frame as
2540 // destination of the thumbnail header animation. If this is a full screen
2541 // window scenario, we use the whole display as the target.
2542 WindowState win = findMainWindow();
2543 Rect appRect = win != null ? win.getContentFrameLw() :
2544 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
chaviw9c81e632018-07-31 11:17:52 -07002545 final Rect insets = win != null ? win.getContentInsets() : null;
Jorim Jaggi988f6682017-11-17 17:46:43 +01002546 final Configuration displayConfig = mDisplayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002547 return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
Jorim Jaggi988f6682017-11-17 17:46:43 +01002548 appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
2549 displayConfig.orientation);
2550 }
2551
2552 private void clearThumbnail() {
2553 if (mThumbnail == null) {
2554 return;
2555 }
2556 mThumbnail.destroy();
2557 mThumbnail = null;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002558 }
2559
Jorim Jaggif84e2f62018-01-16 14:17:59 +01002560 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
2561 mRemoteAnimationDefinition = definition;
2562 }
2563
2564 RemoteAnimationDefinition getRemoteAnimationDefinition() {
2565 return mRemoteAnimationDefinition;
2566 }
2567
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002568 @Override
2569 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2570 super.dump(pw, prefix, dumpAll);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002571 if (appToken != null) {
Wale Ogunwale72919d22016-12-08 18:58:50 -08002572 pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002573 }
Winson Chung48b25652018-10-22 14:04:30 -07002574 pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08002575 pw.print(prefix); pw.print("task="); pw.println(getTask());
Wale Ogunwale51362492016-09-08 17:49:17 -07002576 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
2577 pw.print(" mOrientation="); pw.println(mOrientation);
Wale Ogunwale89973222017-04-23 18:39:45 -07002578 pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
2579 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
2580 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07002581 if (paused) {
2582 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002583 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08002584 if (mAppStopped) {
2585 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
2586 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002587 if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002588 || allDrawn || mLastAllDrawn) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002589 pw.print(prefix); pw.print("mNumInterestingWindows=");
2590 pw.print(mNumInterestingWindows);
2591 pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002592 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07002593 pw.print(" allDrawn="); pw.print(allDrawn);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002594 pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
Craig Mautner6fbda632012-07-03 09:26:39 -07002595 pw.println(")");
2596 }
2597 if (inPendingTransaction) {
2598 pw.print(prefix); pw.print("inPendingTransaction=");
2599 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002600 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08002601 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002602 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
2603 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08002604 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08002605 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002606 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002607 if (startingWindow != null || startingSurface != null
Wale Ogunwale6c459212017-05-17 08:56:03 -07002608 || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002609 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002610 pw.print(" startingSurface="); pw.print(startingSurface);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002611 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale6c459212017-05-17 08:56:03 -07002612 pw.print(" startingMoved="); pw.print(startingMoved);
2613 pw.println(" mHiddenSetFromTransferredStartingWindow="
2614 + mHiddenSetFromTransferredStartingWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002615 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01002616 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08002617 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002618 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08002619 }
2620 if (mPendingRelaunchCount != 0) {
2621 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01002622 }
Wale Ogunwalee287e192017-04-21 09:30:12 -07002623 if (mRemovingFromDisplay) {
2624 pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
2625 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002626 }
2627
2628 @Override
2629 void setHidden(boolean hidden) {
2630 super.setHidden(hidden);
Winson Chunge55c0192017-08-24 14:50:48 -07002631
2632 if (hidden) {
2633 // Once the app window is hidden, reset the last saved PiP snap fraction
2634 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
2635 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002636 scheduleAnimation();
2637 }
2638
2639 @Override
2640 void prepareSurfaces() {
2641 // isSelfAnimating also returns true when we are about to start a transition, so we need
2642 // to check super here.
2643 final boolean reallyAnimating = super.isSelfAnimating();
2644 final boolean show = !isHidden() || reallyAnimating;
2645 if (show && !mLastSurfaceShowing) {
2646 mPendingTransaction.show(mSurfaceControl);
2647 } else if (!show && mLastSurfaceShowing) {
2648 mPendingTransaction.hide(mSurfaceControl);
Jorim Jaggi4d1835d2017-08-31 17:28:27 +02002649 }
Jorim Jaggi988f6682017-11-17 17:46:43 +01002650 if (mThumbnail != null) {
2651 mThumbnail.setShowing(mPendingTransaction, show);
2652 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002653 mLastSurfaceShowing = show;
2654 super.prepareSurfaces();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002655 }
2656
Jorim Jaggi77d0f36c2018-03-16 17:49:49 +01002657 /**
2658 * @return Whether our {@link #getSurfaceControl} is currently showing.
2659 */
2660 boolean isSurfaceShowing() {
2661 return mLastSurfaceShowing;
2662 }
2663
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002664 boolean isFreezingScreen() {
2665 return mFreezingScreen;
2666 }
2667
2668 @Override
2669 boolean needsZBoost() {
2670 return mNeedsZBoost || super.needsZBoost();
2671 }
2672
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07002673 @CallSuper
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002674 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02002675 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07002676 final long token = proto.start(fieldId);
2677 writeNameToProto(proto, NAME);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002678 super.writeToProto(proto, WINDOW_TOKEN, trim);
Vishnu Nair04ab4392018-01-10 11:00:06 -08002679 proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
2680 proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
2681 proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
2682 if (mThumbnail != null){
2683 mThumbnail.writeToProto(proto, THUMBNAIL);
2684 }
2685 proto.write(FILLS_PARENT, mFillsParent);
2686 proto.write(APP_STOPPED, mAppStopped);
2687 proto.write(HIDDEN_REQUESTED, hiddenRequested);
2688 proto.write(CLIENT_HIDDEN, mClientHidden);
2689 proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
2690 proto.write(REPORTED_DRAWN, reportedDrawn);
2691 proto.write(REPORTED_VISIBLE, reportedVisible);
2692 proto.write(NUM_INTERESTING_WINDOWS, mNumInterestingWindows);
2693 proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
2694 proto.write(ALL_DRAWN, allDrawn);
2695 proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
2696 proto.write(REMOVED, removed);
2697 if (startingWindow != null){
2698 startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
2699 }
2700 proto.write(STARTING_DISPLAYED, startingDisplayed);
2701 proto.write(STARTING_MOVED, startingMoved);
2702 proto.write(HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW,
2703 mHiddenSetFromTransferredStartingWindow);
2704 for (Rect bounds : mFrozenBounds) {
2705 bounds.writeToProto(proto, FROZEN_BOUNDS);
2706 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002707 proto.end(token);
2708 }
2709
2710 void writeNameToProto(ProtoOutputStream proto, long fieldId) {
2711 if (appToken == null) {
2712 return;
2713 }
2714 try {
2715 proto.write(fieldId, appToken.getName());
2716 } catch (RemoteException e) {
2717 // This shouldn't happen, but in this case fall back to outputting nothing
2718 Slog.e(TAG, e.toString());
2719 }
2720 }
2721
2722 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002723 public String toString() {
2724 if (stringName == null) {
2725 StringBuilder sb = new StringBuilder();
2726 sb.append("AppWindowToken{");
2727 sb.append(Integer.toHexString(System.identityHashCode(this)));
2728 sb.append(" token="); sb.append(token); sb.append('}');
2729 stringName = sb.toString();
2730 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002731 return stringName + ((mIsExiting) ? " mIsExiting=" : "");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002732 }
Adrian Roos20e07892018-02-23 19:12:01 +01002733
2734 Rect getLetterboxInsets() {
2735 if (mLetterbox != null) {
2736 return mLetterbox.getInsets();
2737 } else {
2738 return new Rect();
2739 }
2740 }
Adrian Roos23df3a32018-03-15 15:41:13 +01002741
2742 /**
2743 * @eturn true if there is a letterbox and any part of that letterbox overlaps with
2744 * the given {@code rect}.
2745 */
2746 boolean isLetterboxOverlappingWith(Rect rect) {
2747 return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
2748 }
chaviw4ad54912018-05-30 11:05:44 -07002749
2750 /**
2751 * Sets if this AWT is in the process of closing or entering PIP.
2752 * {@link #mWillCloseOrEnterPip}}
2753 */
2754 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
2755 mWillCloseOrEnterPip = willCloseOrEnterPip;
2756 }
2757
2758 /**
2759 * Returns whether this AWT is considered closing. Conditions are either
2760 * 1. Is this app animating and was requested to be hidden
2761 * 2. App is delayed closing since it might enter PIP.
2762 */
2763 boolean isClosingOrEnteringPip() {
2764 return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
2765 }
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +02002766
2767 /**
2768 * @return Whether we are allowed to show non-starting windows at the moment. We disallow
2769 * showing windows during transitions in case we have windows that have wide-color-gamut
2770 * color mode set to avoid jank in the middle of the transition.
2771 */
2772 boolean canShowWindows() {
2773 return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
2774 }
2775
2776 /**
2777 * @return true if we have a window that has a non-default color mode set; false otherwise.
2778 */
2779 private boolean hasNonDefaultColorWindow() {
2780 return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
2781 true /* topToBottom */);
2782 }
lumark588a3e82018-07-20 18:53:54 +08002783
2784 void removeFromPendingTransition() {
2785 if (isWaitingForTransitionStart() && mDisplayContent != null) {
2786 mDisplayContent.mOpeningApps.remove(this);
2787 mDisplayContent.mClosingApps.remove(this);
2788 }
2789 }
Jeff Browne9bdb312012-04-05 15:30:10 -07002790}