blob: 76b9b02fac868ceec8a14c4b2840a458ee214a70 [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;
Jorim Jaggife762342016-10-13 14:33:27 +020028import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020029import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080030import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020031import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070032import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080033import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070034import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080035import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
chaviw9c81e632018-07-31 11:17:52 -070036import static android.view.WindowManager.TRANSIT_UNSET;
Jorim Jaggic6976f02018-04-18 16:31:07 +020037import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
chaviw9c81e632018-07-31 11:17:52 -070038
Adrian Roose99bc052017-11-20 17:55:31 +010039import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
40import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070041import static com.android.server.wm.AppWindowTokenProto.ALL_DRAWN;
42import static com.android.server.wm.AppWindowTokenProto.APP_STOPPED;
43import static com.android.server.wm.AppWindowTokenProto.CLIENT_HIDDEN;
44import static com.android.server.wm.AppWindowTokenProto.DEFER_HIDING_CLIENT;
45import static com.android.server.wm.AppWindowTokenProto.FILLS_PARENT;
46import static com.android.server.wm.AppWindowTokenProto.FROZEN_BOUNDS;
47import static com.android.server.wm.AppWindowTokenProto.HIDDEN_REQUESTED;
48import static com.android.server.wm.AppWindowTokenProto.HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW;
49import static com.android.server.wm.AppWindowTokenProto.IS_REALLY_ANIMATING;
50import static com.android.server.wm.AppWindowTokenProto.IS_WAITING_FOR_TRANSITION_START;
51import static com.android.server.wm.AppWindowTokenProto.LAST_ALL_DRAWN;
52import static com.android.server.wm.AppWindowTokenProto.LAST_SURFACE_SHOWING;
53import static com.android.server.wm.AppWindowTokenProto.NAME;
54import static com.android.server.wm.AppWindowTokenProto.NUM_DRAWN_WINDOWS;
55import static com.android.server.wm.AppWindowTokenProto.NUM_INTERESTING_WINDOWS;
56import static com.android.server.wm.AppWindowTokenProto.REMOVED;
57import static com.android.server.wm.AppWindowTokenProto.REPORTED_DRAWN;
58import static com.android.server.wm.AppWindowTokenProto.REPORTED_VISIBLE;
59import static com.android.server.wm.AppWindowTokenProto.STARTING_DISPLAYED;
60import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED;
61import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
62import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
63import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
chaviw9c81e632018-07-31 11:17:52 -070064import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
65import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
67import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
68import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
69import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
70import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
71import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
72import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
73import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
74import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
75import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
76import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
77import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
78import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
79import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
80import static com.android.server.wm.WindowManagerService.logWithStack;
Vishnu Naira2977262018-07-26 13:31:26 -070081import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080082
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070083import android.annotation.CallSuper;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020084import android.app.Activity;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080085import android.app.ActivityManager;
Winson Chung48b25652018-10-22 14:04:30 -070086import android.content.ComponentName;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080087import android.content.res.CompatibilityInfo;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070088import android.content.res.Configuration;
Jorim Jaggi988f6682017-11-17 17:46:43 +010089import android.graphics.GraphicBuffer;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020090import android.graphics.Point;
Jorim Jaggi0429f352015-12-22 16:29:16 +010091import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070092import android.os.Binder;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080093import android.os.Build;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -080094import android.os.Debug;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070095import android.os.IBinder;
Steven Timotiusaf03df62017-07-18 16:56:43 -070096import android.os.RemoteException;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080097import android.os.SystemClock;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020098import android.os.Trace;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080099import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700100import android.util.proto.ProtoOutputStream;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200101import android.view.DisplayInfo;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800102import android.view.IApplicationToken;
Robert Carr788f5742018-07-30 17:46:45 -0700103import android.view.InputApplicationHandle;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100104import android.view.RemoteAnimationDefinition;
Robert Carr6914f082017-03-20 19:04:30 -0700105import android.view.SurfaceControl;
Tony Mak64b8d562017-12-28 17:44:02 +0000106import android.view.SurfaceControl.Transaction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800107import android.view.WindowManager;
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200108import android.view.WindowManager.LayoutParams;
Tony Mak64b8d562017-12-28 17:44:02 +0000109import android.view.animation.Animation;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800110
Tony Mak64b8d562017-12-28 17:44:02 +0000111import com.android.internal.R;
Riddle Hsua118b3a2018-10-11 22:05:06 +0800112import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800113import com.android.internal.util.ToBooleanFunction;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800114import com.android.server.AttributeCache;
115import com.android.server.policy.WindowManagerPolicy;
Adrian Roose99bc052017-11-20 17:55:31 +0100116import com.android.server.policy.WindowManagerPolicy.StartingSurface;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800117import com.android.server.wm.WindowManagerService.H;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800118
119import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +0100120import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800121import java.util.ArrayList;
lumark588a3e82018-07-20 18:53:54 +0800122import java.util.function.Consumer;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800123
124class AppTokenList extends ArrayList<AppWindowToken> {
125}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800126
127/**
128 * Version of WindowToken that is specifically for a particular application (or
129 * really activity) that is displaying windows.
130 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800131class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener,
132 ConfigurationContainerListener {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800133 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
134
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100135 /**
136 * Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
137 */
138 private static final int Z_BOOST_BASE = 800570000;
139
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800140 // Non-null only for application tokens.
141 final IApplicationToken appToken;
Winson Chung48b25652018-10-22 14:04:30 -0700142 final ComponentName mActivityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800143 final boolean mVoiceInteraction;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700144
Wale Ogunwale51362492016-09-08 17:49:17 -0700145 /** @see WindowContainer#fillsParent() */
146 private boolean mFillsParent;
Craig Mautner4c5eb222013-11-18 12:59:05 -0800147 boolean layoutConfigChanges;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800148 boolean mShowForAllUsers;
149 int mTargetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -0700150
Bryce Lee6d410262017-02-28 15:30:17 -0800151 // Flag set while reparenting to prevent actions normally triggered by an individual parent
152 // change.
153 private boolean mReparenting;
154
Wale Ogunwalee287e192017-04-21 09:30:12 -0700155 // True if we are current in the process of removing this app token from the display
156 private boolean mRemovingFromDisplay = false;
157
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800158 // The input dispatching timeout for this application token in nanoseconds.
Wale Ogunwale72919d22016-12-08 18:58:50 -0800159 long mInputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800160
161 // These are used for determining when all windows associated with
162 // an activity have been drawn, so they can be made visible together
163 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -0700164 // initialize so that it doesn't match mTransactionSequence which is an int.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700165 private long mLastTransactionSequence = Long.MIN_VALUE;
166 private int mNumInterestingWindows;
167 private int mNumDrawnWindows;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800168 boolean inPendingTransaction;
169 boolean allDrawn;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000170 private boolean mLastAllDrawn;
171
Craig Mautner7636dfb2012-11-16 15:24:11 -0800172 // Set to true when this app creates a surface while in the middle of an animation. In that
173 // case do not clear allDrawn until the animation completes.
174 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800175
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800176 // Is this window's surface needed? This is almost like hidden, except
177 // it will sometimes be true a little earlier: when the token has
178 // been shown, but is still waiting for its app transition to execute
179 // before making its windows shown.
180 boolean hiddenRequested;
181
182 // Have we told the window clients to hide themselves?
Wale Ogunwale89973222017-04-23 18:39:45 -0700183 private boolean mClientHidden;
184
185 // If true we will defer setting mClientHidden to true and reporting to the client that it is
186 // hidden.
187 boolean mDeferHidingClient;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800188
189 // Last visibility state we reported to the app token.
190 boolean reportedVisible;
191
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700192 // Last drawn state we reported to the app token.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700193 private boolean reportedDrawn;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700194
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800195 // Set to true when the token has been removed from the window mgr.
196 boolean removed;
197
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800198 // Information about an application starting window if displayed.
199 StartingData startingData;
200 WindowState startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800201 StartingSurface startingSurface;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800202 boolean startingDisplayed;
203 boolean startingMoved;
Jorim Jaggi60f9c972018-02-01 19:21:07 +0100204
Wale Ogunwale6c459212017-05-17 08:56:03 -0700205 // True if the hidden state of this token was forced to false due to a transferred starting
206 // window.
207 private boolean mHiddenSetFromTransferredStartingWindow;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800208 boolean firstWindowDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700209 private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
210 new WindowState.UpdateReportedVisibilityResults();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800211
212 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700213 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800214
Wale Ogunwale571771c2016-08-26 13:18:50 -0700215 // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
Craig Mautner799bc1d2015-01-14 10:33:48 -0800216 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800217
Craig Mautnerbb742462014-07-07 15:28:55 -0700218 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700219 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700220
Wale Ogunwale72919d22016-12-08 18:58:50 -0800221 private boolean mAlwaysFocusable;
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800222
Robert Carre12aece2016-02-02 22:43:27 -0800223 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700224 int mRotationAnimationHint;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700225 private int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800226
Jorim Jaggife762342016-10-13 14:33:27 +0200227 private boolean mLastContainsShowWhenLockedWindow;
228 private boolean mLastContainsDismissKeyguardWindow;
229
Jorim Jaggi0429f352015-12-22 16:29:16 +0100230 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700231 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100232
Wale Ogunwale6c459212017-05-17 08:56:03 -0700233 private boolean mDisablePreviewScreenshots;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +0100234
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700235 private Task mLastParent;
Robert Carred3e83b2017-04-21 13:26:55 -0700236
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800237 // TODO: Remove after unification
238 ActivityRecord mActivityRecord;
239
chaviwd3bf08d2017-08-01 17:24:59 -0700240 /**
241 * See {@link #canTurnScreenOn()}
242 */
243 private boolean mCanTurnScreenOn = true;
244
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200245 /**
246 * If we are running an animation, this determines the transition type. Must be one of
247 * AppTransition.TRANSIT_* constants.
248 */
249 private int mTransit;
250
251 /**
252 * If we are running an animation, this determines the flags during this animation. Must be a
253 * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
254 */
255 private int mTransitFlags;
256
257 /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
Jorim Jaggifd1891462017-12-29 15:41:36 +0100258 private boolean mLastSurfaceShowing = true;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200259
Jorim Jaggi988f6682017-11-17 17:46:43 +0100260 private AppWindowThumbnail mThumbnail;
261
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000262 /** Have we been asked to have this token keep the screen frozen? */
263 private boolean mFreezingScreen;
264
265 /** Whether this token should be boosted at the top of all app window tokens. */
266 private boolean mNeedsZBoost;
Adrian Roos4d18a2e2017-12-19 19:08:05 +0100267 private Letterbox mLetterbox;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000268
chaviw23ee71c2017-12-18 11:29:41 -0800269 private final Point mTmpPoint = new Point();
chaviw23012112017-12-20 15:29:04 -0800270 private final Rect mTmpRect = new Rect();
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100271 private RemoteAnimationDefinition mRemoteAnimationDefinition;
Jorim Jaggi6de61012018-03-19 14:53:23 +0100272 private AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry;
chaviw23ee71c2017-12-18 11:29:41 -0800273
chaviw4ad54912018-05-30 11:05:44 -0700274 /**
275 * A flag to determine if this AWT is in the process of closing or entering PIP. This is needed
276 * to help AWT know that the app is in the process of closing but hasn't yet started closing on
277 * the WM side.
278 */
279 private boolean mWillCloseOrEnterPip;
280
Vishnu Naira2977262018-07-26 13:31:26 -0700281 /** Layer used to constrain the animation to a token's stack bounds. */
282 SurfaceControl mAnimationBoundsLayer;
283
284 /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
285 boolean mNeedsAnimationBoundsLayer;
286
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800287 private static final int STARTING_WINDOW_TYPE_NONE = 0;
288 private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
289 private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
290
Winson Chung48b25652018-10-22 14:04:30 -0700291 AppWindowToken(WindowManagerService service, IApplicationToken token,
292 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
293 long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
294 int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
295 boolean launchTaskBehind, boolean alwaysFocusable,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800296 ActivityRecord activityRecord) {
Winson Chung48b25652018-10-22 14:04:30 -0700297 this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800298 // TODO: remove after unification
299 mActivityRecord = activityRecord;
300 mActivityRecord.registerConfigurationChangeListener(this);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800301 mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800302 mShowForAllUsers = showForAllUsers;
303 mTargetSdk = targetSdk;
304 mOrientation = orientation;
305 layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0;
306 mLaunchTaskBehind = launchTaskBehind;
307 mAlwaysFocusable = alwaysFocusable;
308 mRotationAnimationHint = rotationAnimationHint;
309
310 // Application tokens start out hidden.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200311 setHidden(true);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800312 hiddenRequested = true;
313 }
314
Winson Chung48b25652018-10-22 14:04:30 -0700315 AppWindowToken(WindowManagerService service, IApplicationToken token,
316 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
317 boolean fillsParent) {
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800318 super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
319 false /* ownerCanManageAppTokens */);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700320 appToken = token;
Winson Chung48b25652018-10-22 14:04:30 -0700321 mActivityComponent = activityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800322 mVoiceInteraction = voiceInteraction;
Wale Ogunwale17f175c2017-02-07 16:54:10 -0800323 mFillsParent = fillsParent;
Robert Carr0bcbe642018-10-11 19:07:43 -0700324 mInputApplicationHandle = new InputApplicationHandle(appToken.asBinder());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800325 }
326
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800327 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
328 firstWindowDrawn = true;
329
330 // We now have a good window to show, remove dead placeholders
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700331 removeDeadWindows();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800332
Jorim Jaggi02886a82016-12-06 09:10:06 -0800333 if (startingWindow != null) {
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800334 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
335 + win.mToken + ": first real window is shown, no animation");
336 // If this initial window is animating, stop it -- we will do an animation to reveal
337 // it from behind the starting window, so there is no need for it to also be doing its
338 // own stuff.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100339 win.cancelAnimation();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800340 removeStartingWindow();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800341 }
342 updateReportedVisibilityLocked();
343 }
344
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800345 void updateReportedVisibilityLocked() {
346 if (appToken == null) {
347 return;
348 }
349
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700350 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700351 final int count = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800352
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700353 mReportedVisibilityResults.reset();
354
355 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700356 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700357 win.updateReportedVisibility(mReportedVisibilityResults);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800358 }
359
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700360 int numInteresting = mReportedVisibilityResults.numInteresting;
361 int numVisible = mReportedVisibilityResults.numVisible;
362 int numDrawn = mReportedVisibilityResults.numDrawn;
363 boolean nowGone = mReportedVisibilityResults.nowGone;
364
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700365 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200366 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !isHidden();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700367 if (!nowGone) {
368 // If the app is not yet gone, then it can only become visible/drawn.
369 if (!nowDrawn) {
370 nowDrawn = reportedDrawn;
371 }
372 if (!nowVisible) {
373 nowVisible = reportedVisible;
374 }
375 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800376 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800377 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700378 if (nowDrawn != reportedDrawn) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800379 if (mActivityRecord != null) {
380 mActivityRecord.onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700381 }
382 reportedDrawn = nowDrawn;
383 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800384 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700385 if (DEBUG_VISIBILITY) Slog.v(TAG,
386 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800387 reportedVisible = nowVisible;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800388 if (mActivityRecord != null) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800389 if (nowVisible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800390 onWindowsVisible();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800391 } else {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800392 onWindowsGone();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800393 }
394 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800395 }
396 }
397
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800398 private void onWindowsGone() {
399 if (mActivityRecord == null) {
400 return;
401 }
402 if (DEBUG_VISIBILITY) {
403 Slog.v(TAG_WM, "Reporting gone in " + mActivityRecord.appToken);
404 }
405 mActivityRecord.onWindowsGone();
406 }
407
408 private void onWindowsVisible() {
409 if (mActivityRecord == null) {
410 return;
411 }
412 if (DEBUG_VISIBILITY) {
413 Slog.v(TAG_WM, "Reporting visible in " + mActivityRecord.appToken);
414 }
415 mActivityRecord.onWindowsVisible();
416 }
417
Wale Ogunwale89973222017-04-23 18:39:45 -0700418 boolean isClientHidden() {
419 return mClientHidden;
420 }
421
422 void setClientHidden(boolean hideClient) {
423 if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
424 return;
425 }
Jorim Jaggi067b5bf2018-02-23 17:42:39 +0100426 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
427 + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
Wale Ogunwale89973222017-04-23 18:39:45 -0700428 mClientHidden = hideClient;
429 sendAppVisibilityToClients();
430 }
431
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800432 void setVisibility(boolean visible, boolean deferHidingClient) {
433 final AppTransition appTransition = getDisplayContent().mAppTransition;
434
435 // Don't set visibility to false if we were already not visible. This prevents WM from
436 // adding the app to the closing app list which doesn't make sense for something that is
437 // already not visible. However, set visibility to true even if we are already visible.
438 // This makes sure the app is added to the opening apps list so that the right
439 // transition can be selected.
440 // TODO: Probably a good idea to separate the concept of opening/closing apps from the
441 // concept of setting visibility...
442 if (!visible && hiddenRequested) {
443
444 if (!deferHidingClient && mDeferHidingClient) {
445 // We previously deferred telling the client to hide itself when visibility was
446 // initially set to false. Now we would like it to hide, so go ahead and set it.
447 mDeferHidingClient = deferHidingClient;
448 setClientHidden(true);
449 }
450 return;
451 }
452
453 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
454 Slog.v(TAG_WM, "setAppVisibility("
455 + appToken + ", visible=" + visible + "): " + appTransition
456 + " hidden=" + isHidden() + " hiddenRequested="
457 + hiddenRequested + " Callers=" + Debug.getCallers(6));
458 }
459
460 final DisplayContent displayContent = getDisplayContent();
461 displayContent.mOpeningApps.remove(this);
462 displayContent.mClosingApps.remove(this);
463 waitingToShow = false;
464 hiddenRequested = !visible;
465 mDeferHidingClient = deferHidingClient;
466
467 if (!visible) {
468 // If the app is dead while it was visible, we kept its dead window on screen.
469 // Now that the app is going invisible, we can remove it. It will be restarted
470 // if made visible again.
471 removeDeadWindows();
472 } else {
473 if (!appTransition.isTransitionSet()
474 && appTransition.isReady()) {
475 // Add the app mOpeningApps if transition is unset but ready. This means
476 // we're doing a screen freeze, and the unfreeze will wait for all opening
477 // apps to be ready.
478 displayContent.mOpeningApps.add(this);
479 }
480 startingMoved = false;
481 // If the token is currently hidden (should be the common case), or has been
482 // stopped, then we need to set up to wait for its windows to be ready.
483 if (isHidden() || mAppStopped) {
484 clearAllDrawn();
485
486 // If the app was already visible, don't reset the waitingToShow state.
487 if (isHidden()) {
488 waitingToShow = true;
489 }
490 }
491
492 // In the case where we are making an app visible but holding off for a transition,
493 // we still need to tell the client to make its windows visible so they get drawn.
494 // Otherwise, we will wait on performing the transition until all windows have been
495 // drawn, they never will be, and we are sad.
496 setClientHidden(false);
497
498 requestUpdateWallpaperIfNeeded();
499
500 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + this);
501 mAppStopped = false;
502
503 transferStartingWindowFromHiddenAboveTokenIfNeeded();
504 }
505
506 // If we are preparing an app transition, then delay changing
507 // the visibility of this token until we execute that transition.
508 if (okToAnimate() && appTransition.isTransitionSet()) {
509 inPendingTransaction = true;
510 if (visible) {
511 displayContent.mOpeningApps.add(this);
512 mEnteringAnimation = true;
513 } else {
514 displayContent.mClosingApps.add(this);
515 mEnteringAnimation = false;
516 }
517 if (appTransition.getAppTransition()
518 == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
519 // We're launchingBehind, add the launching activity to mOpeningApps.
520 final WindowState win = getDisplayContent().findFocusedWindow();
521 if (win != null) {
522 final AppWindowToken focusedToken = win.mAppToken;
523 if (focusedToken != null) {
524 if (DEBUG_APP_TRANSITIONS) {
525 Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
526 + " adding " + focusedToken + " to mOpeningApps");
527 }
528 // Force animation to be loaded.
529 focusedToken.setHidden(true);
530 displayContent.mOpeningApps.add(focusedToken);
531 }
532 }
533 }
534 return;
535 }
536
537 commitVisibility(null, visible, TRANSIT_UNSET, true, mVoiceInteraction);
538 updateReportedVisibilityLocked();
539 }
540
541 boolean commitVisibility(WindowManager.LayoutParams lp,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700542 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
543
544 boolean delayed = false;
545 inPendingTransaction = false;
Wale Ogunwale9e4721f2017-05-23 19:37:30 -0700546 // Reset the state of mHiddenSetFromTransferredStartingWindow since visibility is actually
547 // been set by the app now.
548 mHiddenSetFromTransferredStartingWindow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700549
550 // Allow for state changes and animation to be applied if:
551 // * token is transitioning visibility state
552 // * or the token was marked as hidden and is exiting before we had a chance to play the
553 // transition animation
554 // * or this is an opening app and windows are being replaced.
555 boolean visibilityChanged = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200556 if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800557 final AccessibilityController accessibilityController =
558 mWmService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700559 boolean changed = false;
560 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200561 "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700562
563 boolean runningAppAnimation = false;
564
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100565 if (transit != WindowManager.TRANSIT_UNSET) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200566 if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700567 delayed = runningAppAnimation = true;
568 }
569 final WindowState window = findMainWindow();
Rhed Jao02655dc2018-10-30 20:44:52 +0800570 if (window != null && accessibilityController != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700571 accessibilityController.onAppWindowTransitionLocked(window, transit);
572 }
573 changed = true;
574 }
575
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700576 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700577 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700578 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700579 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700580 }
581
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200582 setHidden(!visible);
583 hiddenRequested = !visible;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700584 visibilityChanged = true;
585 if (!visible) {
586 stopFreezingScreen(true, true);
587 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700588 // If we are being set visible, and the starting window is not yet displayed,
589 // then make sure it doesn't get displayed.
590 if (startingWindow != null && !startingWindow.isDrawnLw()) {
591 startingWindow.mPolicyVisibility = false;
592 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700593 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -0700594
595 // We are becoming visible, so better freeze the screen with the windows that are
596 // getting visible so we also wait for them.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800597 forAllWindows(mWmService::makeWindowFreezingScreenIfNeededLocked, true);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700598 }
599
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800600 if (DEBUG_APP_TRANSITIONS) {
601 Slog.v(TAG_WM, "commitVisibility: " + this
602 + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
603 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700604
605 if (changed) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800606 getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700607 if (performLayout) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800608 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700609 false /*updateInputWindows*/);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800610 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700611 }
Arthur Hung95b38a92018-07-20 18:56:12 +0800612 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700613 }
614 }
615
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200616 if (isReallyAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700617 delayed = true;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100618 } else {
619
620 // We aren't animating anything, but exiting windows rely on the animation finished
621 // callback being called in case the AppWindowToken was pretending to be animating,
622 // which we might have done because we were in closing/opening apps list.
623 onAnimationFinished();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700624 }
625
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700626 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100627 if ((mChildren.get(i)).isSelfOrChildAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700628 delayed = true;
629 }
630 }
631
632 if (visibilityChanged) {
633 if (visible && !delayed) {
634 // The token was made immediately visible, there will be no entrance animation.
635 // We need to inform the client the enter animation was finished.
636 mEnteringAnimation = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800637 mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(
638 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.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800661 mWmService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
chaviwa953fcf2018-03-01 12:00:39 -0800662 }
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() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800734 if (mTargetSdk < Build.VERSION_CODES.Q) {
735 final int pid = mActivityRecord != null
736 ? (mActivityRecord.app != null ? mActivityRecord.app.getPid() : 0) : 0;
737 final AppWindowToken topFocusedAppOfMyProcess =
738 mWmService.mRoot.mTopFocusedAppByProcess.get(pid);
739 if (topFocusedAppOfMyProcess != null && topFocusedAppOfMyProcess != this) {
740 // For the apps below Q, there can be only one app which has the focused window per
741 // process, because legacy apps may not be ready for a multi-focus system.
742 return false;
743 }
744 }
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700745 return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800746 }
747
Wale Ogunwale571771c2016-08-26 13:18:50 -0700748 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700749 boolean isVisible() {
Wale Ogunwalee471be62016-10-03 07:53:55 -0700750 // If the app token isn't hidden then it is considered visible and there is no need to check
751 // its children windows to see if they are visible.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200752 return !isHidden();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700753 }
754
755 @Override
Wale Ogunwalee287e192017-04-21 09:30:12 -0700756 void removeImmediately() {
757 onRemovedFromDisplay();
Yunfan Chen3a77f282018-12-12 15:47:52 -0800758 if (mActivityRecord != null) {
759 mActivityRecord.unregisterConfigurationChangeListener(this);
760 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700761 super.removeImmediately();
762 }
763
764 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700765 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800766 mIsExiting = false;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800767 removeAllWindowsIfPossible();
Bryce Lee6d410262017-02-28 15:30:17 -0800768 removeImmediately();
Craig Mautnere3119b72015-01-20 15:02:36 -0800769 }
770
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700771 @Override
772 boolean checkCompleteDeferredRemoval() {
773 if (mIsExiting) {
774 removeIfPossible();
775 }
776 return super.checkCompleteDeferredRemoval();
777 }
778
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700779 void onRemovedFromDisplay() {
Wale Ogunwalee287e192017-04-21 09:30:12 -0700780 if (mRemovingFromDisplay) {
781 return;
782 }
783 mRemovingFromDisplay = true;
784
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700785 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
786
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800787 boolean delayed = commitVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700788
lumark588a3e82018-07-20 18:53:54 +0800789 getDisplayContent().mOpeningApps.remove(this);
790 getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800791 mWmService.mTaskSnapshotController.onAppRemoved(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700792 waitingToShow = false;
lumark588a3e82018-07-20 18:53:54 +0800793 if (getDisplayContent().mClosingApps.contains(this)) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700794 delayed = true;
lumark588a3e82018-07-20 18:53:54 +0800795 } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
796 getDisplayContent().mClosingApps.add(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700797 delayed = true;
798 }
799
800 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200801 + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700802
803 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
804 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
805
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800806 if (startingData != null) {
807 removeStartingWindow();
Jorim Jaggi19be6052017-08-03 18:33:43 +0200808 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800809
Winson Chung87e5d552017-04-05 11:49:38 -0700810 // If this window was animating, then we need to ensure that the app transition notifies
lumark588a3e82018-07-20 18:53:54 +0800811 // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
812 // so add to that list now
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200813 if (isSelfAnimating()) {
lumark588a3e82018-07-20 18:53:54 +0800814 getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
Winson Chung87e5d552017-04-05 11:49:38 -0700815 }
816
Wale Ogunwalee287e192017-04-21 09:30:12 -0700817 final TaskStack stack = getStack();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700818 if (delayed && !isEmpty()) {
819 // set the token aside because it has an active animation to be finished
820 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
821 "removeAppToken make exiting: " + this);
Wale Ogunwalee287e192017-04-21 09:30:12 -0700822 if (stack != null) {
823 stack.mExitingAppTokens.add(this);
824 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700825 mIsExiting = true;
826 } else {
827 // Make sure there is no animation running on this token, so any windows associated
828 // with it will be removed as soon as their animations are complete
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200829 cancelAnimation();
Wale Ogunwale3106ae012017-05-16 08:56:37 -0700830 if (stack != null) {
831 stack.mExitingAppTokens.remove(this);
832 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700833 removeIfPossible();
834 }
835
836 removed = true;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700837 stopFreezingScreen(true, true);
Bryce Lee6d410262017-02-28 15:30:17 -0800838
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800839 final DisplayContent dc = getDisplayContent();
840 if (dc.mFocusedApp == this) {
841 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
842 + " displayId=" + dc.getDisplayId());
843 dc.setFocusedApp(null);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800844 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700845 }
846
847 if (!delayed) {
848 updateReportedVisibilityLocked();
849 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700850
851 mRemovingFromDisplay = false;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700852 }
853
Chong Zhange05bcb12016-07-26 17:47:29 -0700854 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700855 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700856 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700857 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700858 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700859 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700860 if (wallpaperMightChange) {
861 requestUpdateWallpaperIfNeeded();
862 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700863 }
864
Robert Carre12aece2016-02-02 22:43:27 -0800865 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700866 destroySurfaces(false /*cleanupOnResume*/);
867 }
868
869 /**
870 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
871 * the client has finished with them.
872 *
873 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
874 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
875 * others so that they are ready to be reused. If set to false (common case), destroy all
876 * surfaces that's eligible, if the app is already stopped.
877 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700878 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700879 boolean destroyedSomething = false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100880
881 // Copying to a different list as multiple children can be removed.
Jorim Jaggi59f3e922018-01-05 15:40:32 +0100882 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100883 for (int i = children.size() - 1; i >= 0; i--) {
884 final WindowState win = children.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700885 destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
Robert Carre12aece2016-02-02 22:43:27 -0800886 }
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700887 if (destroyedSomething) {
888 final DisplayContent dc = getDisplayContent();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700889 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Adrian Roos23df3a32018-03-15 15:41:13 +0100890 updateLetterboxSurface(null);
Robert Carre12aece2016-02-02 22:43:27 -0800891 }
892 }
893
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800894 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700895 * Notify that the app is now resumed, and it was not stopped before, perform a clean
896 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800897 */
Jorim Jaggibae01b12017-04-11 16:29:10 -0700898 void notifyAppResumed(boolean wasStopped) {
Chong Zhangad24f962016-08-25 12:12:33 -0700899 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
Jorim Jaggibae01b12017-04-11 16:29:10 -0700900 + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700901 mAppStopped = false;
chaviwd3bf08d2017-08-01 17:24:59 -0700902 // Allow the window to turn the screen on once the app is resumed again.
903 setCanTurnScreenOn(true);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700904 if (!wasStopped) {
905 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800906 }
Robert Carre12aece2016-02-02 22:43:27 -0800907 }
908
Chong Zhangbef461f2015-10-27 11:38:24 -0700909 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700910 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
911 * keeping alive in case they were still being used.
912 */
913 void notifyAppStopped() {
914 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
915 mAppStopped = true;
916 destroySurfaces();
917 // Remove any starting window that was added for this app if they are still around.
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800918 removeStartingWindow();
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700919 }
920
Chong Zhang92147042016-05-09 12:47:11 -0700921 void clearAllDrawn() {
922 allDrawn = false;
923 deferClearAllDrawn = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700924 }
925
Bryce Lee6d410262017-02-28 15:30:17 -0800926 Task getTask() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800927 return (Task) getParent();
Bryce Lee6d410262017-02-28 15:30:17 -0800928 }
929
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800930 TaskStack getStack() {
931 final Task task = getTask();
932 if (task != null) {
933 return task.mStack;
934 } else {
935 return null;
936 }
937 }
938
Bryce Lee6d410262017-02-28 15:30:17 -0800939 @Override
940 void onParentSet() {
941 super.onParentSet();
942
Robert Carred3e83b2017-04-21 13:26:55 -0700943 final Task task = getTask();
944
Bryce Lee6d410262017-02-28 15:30:17 -0800945 // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
946 // access visual elements like the {@link DisplayContent}. We must remove any associations
947 // such as animations.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800948 if (!mReparenting) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800949 if (task == null) {
950 // It is possible we have been marked as a closing app earlier. We must remove ourselves
951 // from this list so we do not participate in any future animations.
lumark588a3e82018-07-20 18:53:54 +0800952 getDisplayContent().mClosingApps.remove(this);
Robert Carred3e83b2017-04-21 13:26:55 -0700953 } else if (mLastParent != null && mLastParent.mStack != null) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800954 task.mStack.mExitingAppTokens.remove(this);
955 }
Bryce Lee6d410262017-02-28 15:30:17 -0800956 }
Jorim Jaggi6de61012018-03-19 14:53:23 +0100957 final TaskStack stack = getStack();
958
959 // If we reparent, make sure to remove ourselves from the old animation registry.
960 if (mAnimatingAppWindowTokenRegistry != null) {
961 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
962 }
963 mAnimatingAppWindowTokenRegistry = stack != null
964 ? stack.getAnimatingAppWindowTokenRegistry()
965 : null;
966
Robert Carred3e83b2017-04-21 13:26:55 -0700967 mLastParent = task;
Bryce Lee6d410262017-02-28 15:30:17 -0800968 }
969
Wale Ogunwalefa854eb2016-09-20 13:43:52 -0700970 void postWindowRemoveStartingWindowCleanup(WindowState win) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700971 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700972 if (startingWindow == win) {
973 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800974 removeStartingWindow();
Wale Ogunwale6c459212017-05-17 08:56:03 -0700975 } else if (mChildren.size() == 0) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700976 // If this is the last window and we had requested a starting transition window,
977 // well there is no point now.
Jorim Jaggi02886a82016-12-06 09:10:06 -0800978 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700979 startingData = null;
Wale Ogunwale6c459212017-05-17 08:56:03 -0700980 if (mHiddenSetFromTransferredStartingWindow) {
981 // We set the hidden state to false for the token from a transferred starting window.
982 // We now reset it back to true since the starting window was the last window in the
983 // token.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200984 setHidden(true);
Wale Ogunwale6c459212017-05-17 08:56:03 -0700985 }
Jorim Jaggi829b9cd2017-01-23 16:20:53 +0100986 } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700987 // If this is the last window except for a starting transition window,
988 // we need to get rid of the starting transition.
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200989 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
990 + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800991 removeStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700992 }
993 }
994
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700995 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700996 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700997 WindowState win = mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800998 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700999 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001000 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -08001001 // Set mDestroying, we don't want any animation or delayed removal here.
1002 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001003 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001004 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -08001005 }
1006 }
1007 }
1008
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001009 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001010 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001011 // No need to loop through child windows as the answer should be the same as that of the
1012 // parent window.
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001013 if (!(mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001014 return true;
1015 }
1016 }
1017 return false;
1018 }
1019
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001020 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001021 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1022 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -08001023
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001024 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001025 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001026 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -08001027 }
Robert Carra1eb4392015-12-10 12:43:51 -08001028 }
1029
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001030 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001031 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -08001032 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001033 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001034 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001035 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -08001036 }
1037 }
1038
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001039 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001040 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1041 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -08001042
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001043 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001044 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001045 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -08001046 }
1047 }
1048
Chong Zhang4d7369a2016-04-25 16:09:14 -07001049 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001050 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001051 final WindowState w = mChildren.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -07001052 w.requestUpdateWallpaperIfNeeded();
1053 }
1054 }
1055
Chong Zhangd78ddb42016-03-02 17:01:14 -08001056 boolean isRelaunching() {
1057 return mPendingRelaunchCount > 0;
1058 }
1059
Robert Carr68375192017-06-13 12:41:53 -07001060 boolean shouldFreezeBounds() {
1061 final Task task = getTask();
1062
1063 // For freeform windows, we can't freeze the bounds at the moment because this would make
1064 // the resizing unresponsive.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001065 if (task == null || task.inFreeformWindowingMode()) {
Robert Carr68375192017-06-13 12:41:53 -07001066 return false;
1067 }
1068
1069 // We freeze the bounds while drag resizing to deal with the time between
1070 // the divider/drag handle being released, and the handling it's new
1071 // configuration. If we are relaunched outside of the drag resizing state,
1072 // we need to be careful not to do this.
1073 return getTask().isDragResizing();
1074 }
1075
Chong Zhangd78ddb42016-03-02 17:01:14 -08001076 void startRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001077 if (shouldFreezeBounds()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001078 freezeBounds();
1079 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001080
1081 // In the process of tearing down before relaunching, the app will
1082 // try and clean up it's child surfaces. We need to prevent this from
1083 // happening, so we sever the children, transfering their ownership
1084 // from the client it-self to the parent surface (owned by us).
Robert Carr29daa922018-04-27 11:56:48 -07001085 detachChildren();
1086
1087 mPendingRelaunchCount++;
1088 }
1089
1090 void detachChildren() {
Robert Carrfd8e93b2018-05-10 13:40:25 -07001091 SurfaceControl.openTransaction();
Robert Carrd5c7dd62017-03-08 10:39:30 -08001092 for (int i = mChildren.size() - 1; i >= 0; i--) {
1093 final WindowState w = mChildren.get(i);
1094 w.mWinAnimator.detachChildren();
1095 }
Robert Carrfd8e93b2018-05-10 13:40:25 -07001096 SurfaceControl.closeTransaction();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001097 }
1098
1099 void finishRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001100 unfreezeBounds();
1101
Chong Zhangd78ddb42016-03-02 17:01:14 -08001102 if (mPendingRelaunchCount > 0) {
1103 mPendingRelaunchCount--;
Bryce Lee081554b2017-05-25 07:52:12 -07001104 } else {
1105 // Update keyguard flags upon finishing relaunch.
1106 checkKeyguardFlagsChanged();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001107 }
1108 }
1109
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001110 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001111 if (mPendingRelaunchCount == 0) {
1112 return;
1113 }
Robert Carr68375192017-06-13 12:41:53 -07001114 unfreezeBounds();
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001115 mPendingRelaunchCount = 0;
1116 }
1117
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001118 /**
1119 * Returns true if the new child window we are adding to this token is considered greater than
1120 * the existing child window in this token in terms of z-order.
1121 */
1122 @Override
1123 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
1124 WindowState existingWindow) {
1125 final int type1 = newWindow.mAttrs.type;
1126 final int type2 = existingWindow.mAttrs.type;
1127
1128 // Base application windows should be z-ordered BELOW all other windows in the app token.
1129 if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
1130 return false;
1131 } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
1132 return true;
1133 }
1134
1135 // Starting windows should be z-ordered ABOVE all other windows in the app token.
1136 if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
1137 return true;
1138 } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
1139 return false;
1140 }
1141
1142 // Otherwise the new window is greater than the existing window.
1143 return true;
1144 }
1145
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001146 @Override
Robert Carra1eb4392015-12-10 12:43:51 -08001147 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001148 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001149
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001150 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001151 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001152 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001153 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
1154 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001155
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001156 // if we got a replacement window, reset the timeout to give drawing more time
1157 if (gotReplacementWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001158 mWmService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -08001159 }
Jorim Jaggife762342016-10-13 14:33:27 +02001160 checkKeyguardFlagsChanged();
1161 }
1162
1163 @Override
1164 void removeChild(WindowState child) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001165 if (!mChildren.contains(child)) {
1166 // This can be true when testing.
1167 return;
1168 }
Jorim Jaggife762342016-10-13 14:33:27 +02001169 super.removeChild(child);
1170 checkKeyguardFlagsChanged();
Adrian Roos23df3a32018-03-15 15:41:13 +01001171 updateLetterboxSurface(child);
Robert Carra1eb4392015-12-10 12:43:51 -08001172 }
1173
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001174 private boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001175 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001176 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001177 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -08001178 return true;
1179 }
1180 }
1181 return false;
1182 }
1183
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001184 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001185 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001186 (mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -08001187 }
1188 }
1189
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001190 void reparent(Task task, int position) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001191 if (DEBUG_ADD_REMOVE) {
1192 Slog.i(TAG_WM, "reparent: moving app token=" + this
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001193 + " to task=" + task.mTaskId + " at " + position);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001194 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001195 if (task == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001196 throw new IllegalArgumentException("reparent: could not find task");
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001197 }
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001198 final Task currentTask = getTask();
1199 if (task == currentTask) {
Winson Chung30480042017-01-26 10:55:34 -08001200 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001201 "window token=" + this + " already child of task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001202 }
Bryce Lee6d410262017-02-28 15:30:17 -08001203
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001204 if (currentTask.mStack != task.mStack) {
Bryce Lee6d410262017-02-28 15:30:17 -08001205 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001206 "window token=" + this + " current task=" + currentTask
Bryce Lee6d410262017-02-28 15:30:17 -08001207 + " belongs to a different stack than " + task);
1208 }
1209
Winson Chung30480042017-01-26 10:55:34 -08001210 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001211 + " from task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001212 final DisplayContent prevDisplayContent = getDisplayContent();
1213
Bryce Lee6d410262017-02-28 15:30:17 -08001214 mReparenting = true;
1215
Winson Chung30480042017-01-26 10:55:34 -08001216 getParent().removeChild(this);
1217 task.addChild(this, position);
1218
Bryce Lee6d410262017-02-28 15:30:17 -08001219 mReparenting = false;
1220
Winson Chung30480042017-01-26 10:55:34 -08001221 // Relayout display(s).
1222 final DisplayContent displayContent = task.getDisplayContent();
1223 displayContent.setLayoutNeeded();
1224 if (prevDisplayContent != displayContent) {
1225 onDisplayChanged(displayContent);
1226 prevDisplayContent.setLayoutNeeded();
1227 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001228 getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
Winson Chung30480042017-01-26 10:55:34 -08001229 }
1230
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001231 @Override
1232 void onDisplayChanged(DisplayContent dc) {
1233 DisplayContent prevDc = mDisplayContent;
1234 super.onDisplayChanged(dc);
1235 if (prevDc != null && prevDc.mFocusedApp == this) {
1236 prevDc.setFocusedApp(null);
lumarkbf844642018-11-23 17:11:36 +08001237 final TaskStack stack = dc.getTopStack();
1238 if (stack != null) {
1239 final Task task = stack.getTopChild();
1240 if (task != null && task.getTopChild() == this) {
1241 dc.setFocusedApp(this);
1242 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001243 }
1244 }
1245 }
1246
Jorim Jaggi0429f352015-12-22 16:29:16 +01001247 /**
1248 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
1249 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
1250 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
1251 * with a queue.
1252 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001253 private void freezeBounds() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001254 final Task task = getTask();
1255 mFrozenBounds.offer(new Rect(task.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001256
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001257 if (task.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001258 // We didn't call prepareFreezingBounds on the task, so use the current value.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001259 mFrozenMergedConfig.offer(new Configuration(task.getConfiguration()));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001260 } else {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001261 mFrozenMergedConfig.offer(new Configuration(task.mPreparedFrozenMergedConfig));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001262 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001263 // Calling unset() to make it equal to Configuration.EMPTY.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001264 task.mPreparedFrozenMergedConfig.unset();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001265 }
1266
1267 /**
1268 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
1269 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001270 private void unfreezeBounds() {
Robert Carr68375192017-06-13 12:41:53 -07001271 if (mFrozenBounds.isEmpty()) {
1272 return;
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001273 }
Robert Carr68375192017-06-13 12:41:53 -07001274 mFrozenBounds.remove();
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001275 if (!mFrozenMergedConfig.isEmpty()) {
1276 mFrozenMergedConfig.remove();
1277 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001278 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001279 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001280 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +01001281 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001282 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001283 }
1284
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001285 void setAppLayoutChanges(int changes, String reason) {
1286 if (!mChildren.isEmpty()) {
1287 final DisplayContent dc = getDisplayContent();
1288 dc.pendingLayoutChanges |= changes;
1289 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001290 mWmService.mWindowPlacerLocked.debugLayoutRepeats(reason, dc.pendingLayoutChanges);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001291 }
1292 }
1293 }
1294
1295 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001296 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001297 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001298 if (win.removeReplacedWindowIfNeeded(replacement)) {
1299 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001300 }
1301 }
1302 }
1303
1304 void startFreezingScreen() {
1305 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001306 + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001307 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001308 if (!hiddenRequested) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001309 if (!mFreezingScreen) {
1310 mFreezingScreen = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001311 mWmService.registerAppFreezeListener(this);
1312 mWmService.mAppsFreezingScreen++;
1313 if (mWmService.mAppsFreezingScreen == 1) {
1314 mWmService.startFreezingDisplayLocked(0, 0, getDisplayContent());
1315 mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1316 mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001317 }
1318 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001319 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001320 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001321 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001322 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001323 }
1324 }
1325 }
1326
1327 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001328 if (!mFreezingScreen) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001329 return;
1330 }
1331 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001332 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001333 boolean unfrozeWindows = false;
1334 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001335 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001336 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001337 }
1338 if (force || unfrozeWindows) {
1339 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001340 mFreezingScreen = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001341 mWmService.unregisterAppFreezeListener(this);
1342 mWmService.mAppsFreezingScreen--;
1343 mWmService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001344 }
1345 if (unfreezeSurfaceNow) {
1346 if (unfrozeWindows) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001347 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001348 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001349 mWmService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001350 }
1351 }
1352
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001353 @Override
1354 public void onAppFreezeTimeout() {
1355 Slog.w(TAG_WM, "Force clearing freeze: " + this);
1356 stopFreezingScreen(true, true);
1357 }
1358
Jorim Jaggi60f9c972018-02-01 19:21:07 +01001359 /**
1360 * Tries to transfer the starting window from a token that's above ourselves in the task but
1361 * not visible anymore. This is a common scenario apps use: Trampoline activity T start main
1362 * activity M in the same task. Now, when reopening the task, T starts on top of M but then
1363 * immediately finishes after, so we have to transfer T to M.
1364 */
1365 void transferStartingWindowFromHiddenAboveTokenIfNeeded() {
1366 final Task task = getTask();
1367 for (int i = task.mChildren.size() - 1; i >= 0; i--) {
1368 final AppWindowToken fromToken = task.mChildren.get(i);
1369 if (fromToken == this) {
1370 return;
1371 }
1372 if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) {
1373 return;
1374 }
1375 }
1376 }
1377
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001378 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001379 final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001380 if (fromToken == null) {
1381 return false;
1382 }
1383
1384 final WindowState tStartingWindow = fromToken.startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001385 if (tStartingWindow != null && fromToken.startingSurface != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001386 // In this case, the starting icon has already been displayed, so start
1387 // letting windows get shown immediately without any more transitions.
lumark588a3e82018-07-20 18:53:54 +08001388 getDisplayContent().mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001389
1390 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1391 + " from " + fromToken + " to " + this);
1392
1393 final long origId = Binder.clearCallingIdentity();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001394 try {
1395 // Transfer the starting window over to the new token.
1396 startingData = fromToken.startingData;
1397 startingSurface = fromToken.startingSurface;
1398 startingDisplayed = fromToken.startingDisplayed;
1399 fromToken.startingDisplayed = false;
1400 startingWindow = tStartingWindow;
1401 reportedVisible = fromToken.reportedVisible;
1402 fromToken.startingData = null;
1403 fromToken.startingSurface = null;
1404 fromToken.startingWindow = null;
1405 fromToken.startingMoved = true;
1406 tStartingWindow.mToken = this;
1407 tStartingWindow.mAppToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001408
Peter Visontay3556a3b2017-11-01 17:23:17 +00001409 if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1410 "Removing starting " + tStartingWindow + " from " + fromToken);
1411 fromToken.removeChild(tStartingWindow);
1412 fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
1413 fromToken.mHiddenSetFromTransferredStartingWindow = false;
1414 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001415
Peter Visontay3556a3b2017-11-01 17:23:17 +00001416 // Propagate other interesting state between the tokens. If the old token is displayed,
1417 // we should immediately force the new one to be displayed. If it is animating, we need
1418 // to move that animation to the new one.
1419 if (fromToken.allDrawn) {
1420 allDrawn = true;
1421 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1422 }
1423 if (fromToken.firstWindowDrawn) {
1424 firstWindowDrawn = true;
1425 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001426 if (!fromToken.isHidden()) {
1427 setHidden(false);
Peter Visontay3556a3b2017-11-01 17:23:17 +00001428 hiddenRequested = false;
1429 mHiddenSetFromTransferredStartingWindow = true;
1430 }
1431 setClientHidden(fromToken.mClientHidden);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001432
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001433 transferAnimation(fromToken);
1434
1435 // When transferring an animation, we no longer need to apply an animation to the
1436 // the token we transfer the animation over. Thus, remove the animation from
1437 // pending opening apps.
lumark588a3e82018-07-20 18:53:54 +08001438 getDisplayContent().mOpeningApps.remove(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001439
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001440 mWmService.updateFocusedWindowLocked(
Peter Visontay3556a3b2017-11-01 17:23:17 +00001441 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
1442 getDisplayContent().setLayoutNeeded();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001443 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001444 } finally {
1445 Binder.restoreCallingIdentity(origId);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001446 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001447 return true;
1448 } else if (fromToken.startingData != null) {
1449 // The previous app was getting ready to show a
1450 // starting window, but hasn't yet done so. Steal it!
1451 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1452 "Moving pending starting from " + fromToken + " to " + this);
1453 startingData = fromToken.startingData;
1454 fromToken.startingData = null;
1455 fromToken.startingMoved = true;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001456 scheduleAddStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001457 return true;
1458 }
1459
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001460 // TODO: Transfer thumbnail
1461
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001462 return false;
1463 }
1464
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001465 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001466 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001467 }
1468
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001469 @Override
1470 void onAppTransitionDone() {
1471 sendingToBottom = false;
1472 }
1473
Wale Ogunwale51362492016-09-08 17:49:17 -07001474 /**
1475 * We override because this class doesn't want its children affecting its reported orientation
1476 * in anyway.
1477 */
1478 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001479 int getOrientation(int candidate) {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001480 if (candidate == SCREEN_ORIENTATION_BEHIND) {
1481 // Allow app to specify orientation regardless of its visibility state if the current
1482 // candidate want us to use orientation behind. I.e. the visible app on-top of this one
1483 // wants us to use the orientation of the app behind it.
1484 return mOrientation;
1485 }
1486
Bryce Lee61fbcbc2017-03-10 14:14:03 -08001487 // The {@link AppWindowToken} should only specify an orientation when it is not closing or
1488 // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
1489 // an Activity in another task being started in the wrong orientation during the transition.
lumark588a3e82018-07-20 18:53:54 +08001490 if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
1491 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
Bryce Leea163b762017-01-24 11:05:01 -08001492 return mOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07001493 }
Bryce Leea163b762017-01-24 11:05:01 -08001494
1495 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001496 }
1497
Wale Ogunwaleb198b742016-12-01 08:44:09 -08001498 /** Returns the app's preferred orientation regardless of its currently visibility state. */
1499 int getOrientationIgnoreVisibility() {
1500 return mOrientation;
1501 }
1502
Craig Mautnerdbb79912012-03-01 18:59:14 -08001503 @Override
Winson Chunge55c0192017-08-24 14:50:48 -07001504 public void onConfigurationChanged(Configuration newParentConfig) {
1505 final int prevWinMode = getWindowingMode();
1506 super.onConfigurationChanged(newParentConfig);
1507 final int winMode = getWindowingMode();
1508
1509 if (prevWinMode == winMode) {
1510 return;
1511 }
1512
1513 if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) {
1514 // Entering PiP from fullscreen, reset the snap fraction
1515 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
Winson Chung82267ce2018-04-06 16:38:26 -07001516 } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED
1517 && !isHidden()) {
Winson Chunge55c0192017-08-24 14:50:48 -07001518 // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
1519 // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
1520 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
1521 if (pinnedStack != null) {
Winson Chung8efa1652018-06-06 09:34:23 -07001522 final Rect stackBounds;
1523 if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
1524 // We are animating the bounds, use the pre-animation bounds to save the snap
1525 // fraction
1526 stackBounds = pinnedStack.mPreAnimationBounds;
1527 } else {
1528 // We skip the animation if the fullscreen configuration is not compatible, so
1529 // use the current bounds to calculate the saved snap fraction instead
1530 // (see PinnedActivityStack.skipResizeAnimation())
1531 stackBounds = mTmpRect;
1532 pinnedStack.getBounds(stackBounds);
1533 }
Winson Chunge55c0192017-08-24 14:50:48 -07001534 mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
Winson Chung8efa1652018-06-06 09:34:23 -07001535 stackBounds);
Winson Chunge55c0192017-08-24 14:50:48 -07001536 }
1537 }
1538 }
1539
1540 @Override
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001541 void checkAppWindowsReadyToShow() {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001542 if (allDrawn == mLastAllDrawn) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001543 return;
1544 }
1545
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001546 mLastAllDrawn = allDrawn;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001547 if (!allDrawn) {
1548 return;
1549 }
1550
1551 // The token has now changed state to having all windows shown... what to do, what to do?
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001552 if (mFreezingScreen) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001553 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001554 stopFreezingScreen(false, true);
1555 if (DEBUG_ORIENTATION) Slog.i(TAG,
1556 "Setting mOrientationChangeComplete=true because wtoken " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001557 + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001558 // This will set mOrientationChangeComplete and cause a pass through layout.
1559 setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001560 "checkAppWindowsReadyToShow: freezingScreen");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001561 } else {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001562 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001563
1564 // We can now show all of the drawn windows!
lumark588a3e82018-07-20 18:53:54 +08001565 if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001566 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001567 }
1568 }
1569 }
1570
Matthew Ng5d23afa2017-06-21 16:16:24 -07001571 /**
Bryce Leed390deb2017-06-22 13:14:28 -07001572 * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
1573 * child {@link WindowState}. A child is considered if it has been passed into
1574 * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
1575 * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
1576 * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
1577 *
1578 * @return {@code true} If all children have been considered, {@code false}.
1579 */
1580 private boolean allDrawnStatesConsidered() {
Bryce Lee6311c4b2017-07-06 14:09:29 -07001581 for (int i = mChildren.size() - 1; i >= 0; --i) {
1582 final WindowState child = mChildren.get(i);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001583 if (child.mightAffectAllDrawn() && !child.getDrawnStateEvaluated()) {
Bryce Leed390deb2017-06-22 13:14:28 -07001584 return false;
1585 }
1586 }
1587 return true;
1588 }
1589
1590 /**
Matthew Ng5d23afa2017-06-21 16:16:24 -07001591 * Determines if the token has finished drawing. This should only be called from
1592 * {@link DisplayContent#applySurfaceChangesTransaction}
1593 */
Matthew Ng498c71d2017-04-18 13:55:45 -07001594 void updateAllDrawn() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001595 if (!allDrawn) {
Matthew Ng498c71d2017-04-18 13:55:45 -07001596 // Number of drawn windows can be less when a window is being relaunched, wait for
Bryce Leed390deb2017-06-22 13:14:28 -07001597 // all windows to be launched and drawn for this token be considered all drawn.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001598 final int numInteresting = mNumInterestingWindows;
Bryce Leed390deb2017-06-22 13:14:28 -07001599
1600 // We must make sure that all present children have been considered (determined by
1601 // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
1602 // drawn.
1603 if (numInteresting > 0 && allDrawnStatesConsidered()
1604 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001605 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001606 + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001607 allDrawn = true;
1608 // Force an additional layout pass where
1609 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
Matthew Ng498c71d2017-04-18 13:55:45 -07001610 if (mDisplayContent != null) {
1611 mDisplayContent.setLayoutNeeded();
1612 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001613 mWmService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Robert Carrecc06b32017-04-18 14:25:10 -07001614
Winson Chunge7ba6862017-05-24 12:13:33 -07001615 // Notify the pinned stack upon all windows drawn. If there was an animation in
1616 // progress then this signal will resume that animation.
Wale Ogunwale61911492017-10-11 08:50:50 -07001617 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
Winson Chunge7ba6862017-05-24 12:13:33 -07001618 if (pinnedStack != null) {
1619 pinnedStack.onAllWindowsDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -07001620 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001621 }
1622 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001623 }
1624
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001625 boolean keyDispatchingTimedOut(String reason, int windowPid) {
1626 return mActivityRecord != null && mActivityRecord.keyDispatchingTimedOut(reason, windowPid);
1627 }
1628
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001629 /**
1630 * Updated this app token tracking states for interesting and drawn windows based on the window.
1631 *
1632 * @return Returns true if the input window is considered interesting and drawn while all the
1633 * windows in this app token where not considered drawn as of the last pass.
1634 */
1635 boolean updateDrawnWindowStates(WindowState w) {
Bryce Leed390deb2017-06-22 13:14:28 -07001636 w.setDrawnStateEvaluated(true /*evaluated*/);
1637
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001638 if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001639 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001640 + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001641 }
1642
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001643 if (allDrawn && !mFreezingScreen) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001644 return false;
1645 }
1646
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001647 if (mLastTransactionSequence != mWmService.mTransactionSequence) {
1648 mLastTransactionSequence = mWmService.mTransactionSequence;
Matthew Ng53e66b22018-01-12 17:13:13 -08001649 mNumDrawnWindows = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001650 startingDisplayed = false;
Matthew Ng53e66b22018-01-12 17:13:13 -08001651
1652 // There is the main base application window, even if it is exiting, wait for it
1653 mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001654 }
1655
1656 final WindowStateAnimator winAnimator = w.mWinAnimator;
1657
1658 boolean isInterestingAndDrawn = false;
1659
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001660 if (!allDrawn && w.mightAffectAllDrawn()) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001661 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1662 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001663 + ", isAnimationSet=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001664 if (!w.isDrawnLw()) {
1665 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
1666 + " pv=" + w.mPolicyVisibility
1667 + " mDrawState=" + winAnimator.drawStateToString()
1668 + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001669 + " a=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001670 }
1671 }
1672
1673 if (w != startingWindow) {
1674 if (w.isInteresting()) {
Matthew Ng53e66b22018-01-12 17:13:13 -08001675 // Add non-main window as interesting since the main app has already been added
1676 if (findMainWindow(false /* includeStartingApp */) != w) {
1677 mNumInterestingWindows++;
1678 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001679 if (w.isDrawnLw()) {
1680 mNumDrawnWindows++;
1681
1682 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
1683 + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001684 + " freezingScreen=" + mFreezingScreen
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001685 + " mAppFreezing=" + w.mAppFreezing);
1686
1687 isInterestingAndDrawn = true;
1688 }
1689 }
1690 } else if (w.isDrawnLw()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001691 if (mActivityRecord != null) {
1692 mActivityRecord.onStartingWindowDrawn(SystemClock.uptimeMillis());
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001693 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001694 startingDisplayed = true;
1695 }
1696 }
1697
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001698 return isInterestingAndDrawn;
1699 }
1700
Adrian Roos23df3a32018-03-15 15:41:13 +01001701 void layoutLetterbox(WindowState winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001702 final WindowState w = findMainWindow();
Adrian Roosf93b6d22018-03-21 13:48:26 +01001703 if (w == null || winHint != null && w != winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001704 return;
1705 }
Jorim Jaggia32da382018-03-28 18:01:22 +02001706 final boolean surfaceReady = w.isDrawnLw() // Regular case
Adrian Roosf93b6d22018-03-21 13:48:26 +01001707 || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
1708 || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
1709 final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001710 if (needsLetterbox) {
1711 if (mLetterbox == null) {
1712 mLetterbox = new Letterbox(() -> makeChildSurface(null));
1713 }
Adrian Roos7af9d972018-11-30 15:26:27 +01001714 getPosition(mTmpPoint);
1715 mLetterbox.layout(getParent().getBounds(), w.getFrameLw(), mTmpPoint);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001716 } else if (mLetterbox != null) {
Adrian Roos23df3a32018-03-15 15:41:13 +01001717 mLetterbox.hide();
1718 }
1719 }
1720
1721 void updateLetterboxSurface(WindowState winHint) {
1722 final WindowState w = findMainWindow();
1723 if (w != winHint && winHint != null && w != null) {
1724 return;
1725 }
1726 layoutLetterbox(winHint);
1727 if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
1728 mLetterbox.applySurfaceChanges(mPendingTransaction);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001729 }
1730 }
1731
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001732 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001733 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001734 // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
1735 // before the non-exiting app tokens. So, we skip the exiting app tokens here.
1736 // TODO: Investigate if we need to continue to do this or if we can just process them
1737 // in-order.
1738 if (mIsExiting && !waitingForReplacement()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001739 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001740 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001741 return forAllWindowsUnchecked(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001742 }
1743
lumark588a3e82018-07-20 18:53:54 +08001744 @Override
1745 void forAllAppWindows(Consumer<AppWindowToken> callback) {
1746 callback.accept(this);
1747 }
1748
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001749 boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
1750 boolean traverseTopToBottom) {
1751 return super.forAllWindows(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001752 }
1753
1754 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001755 AppWindowToken asAppWindowToken() {
1756 // I am an app window token!
1757 return this;
1758 }
1759
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001760 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1761 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1762 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1763 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1764 // If the display is frozen, we won't do anything until the actual window is
1765 // displayed so there is no reason to put in the starting window.
1766 if (!okToDisplay()) {
1767 return false;
1768 }
1769
1770 if (startingData != null) {
1771 return false;
1772 }
1773
1774 final WindowState mainWin = findMainWindow();
1775 if (mainWin != null && mainWin.mWinAnimator.getShown()) {
1776 // App already has a visible window...why would you want a starting window?
1777 return false;
1778 }
1779
1780 final ActivityManager.TaskSnapshot snapshot =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001781 mWmService.mTaskSnapshotController.getSnapshot(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001782 getTask().mTaskId, getTask().mUserId,
1783 false /* restoreFromDisk */, false /* reducedResolution */);
1784 final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
1785 allowTaskSnapshot, activityCreated, fromRecents, snapshot);
1786
1787 if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
1788 return createSnapshot(snapshot);
1789 }
1790
1791 // If this is a translucent window, then don't show a starting window -- the current
1792 // effect (a full-screen opaque starting window that fades away to the real contents
1793 // when it is ready) does not work for this.
1794 if (DEBUG_STARTING_WINDOW) {
1795 Slog.v(TAG, "Checking theme of starting window: 0x" + Integer.toHexString(theme));
1796 }
1797 if (theme != 0) {
1798 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
1799 com.android.internal.R.styleable.Window,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001800 mWmService.mCurrentUserId);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001801 if (ent == null) {
1802 // Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
1803 // see that.
1804 return false;
1805 }
1806 final boolean windowIsTranslucent = ent.array.getBoolean(
1807 com.android.internal.R.styleable.Window_windowIsTranslucent, false);
1808 final boolean windowIsFloating = ent.array.getBoolean(
1809 com.android.internal.R.styleable.Window_windowIsFloating, false);
1810 final boolean windowShowWallpaper = ent.array.getBoolean(
1811 com.android.internal.R.styleable.Window_windowShowWallpaper, false);
1812 final boolean windowDisableStarting = ent.array.getBoolean(
1813 com.android.internal.R.styleable.Window_windowDisablePreview, false);
1814 if (DEBUG_STARTING_WINDOW) {
1815 Slog.v(TAG, "Translucent=" + windowIsTranslucent
1816 + " Floating=" + windowIsFloating
1817 + " ShowWallpaper=" + windowShowWallpaper);
1818 }
1819 if (windowIsTranslucent) {
1820 return false;
1821 }
1822 if (windowIsFloating || windowDisableStarting) {
1823 return false;
1824 }
1825 if (windowShowWallpaper) {
1826 if (getDisplayContent().mWallpaperController
1827 .getWallpaperTarget() == null) {
1828 // If this theme is requesting a wallpaper, and the wallpaper
1829 // is not currently visible, then this effectively serves as
1830 // an opaque window and our starting window transition animation
1831 // can still work. We just need to make sure the starting window
1832 // is also showing the wallpaper.
1833 windowFlags |= FLAG_SHOW_WALLPAPER;
1834 } else {
1835 return false;
1836 }
1837 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001838 }
Yunfan Chen8a8c0ed2018-12-18 16:46:32 -08001839
1840 if (transferStartingWindow(transferFrom)) {
1841 return true;
1842 }
1843
1844 // There is no existing starting window, and we don't want to create a splash screen, so
1845 // that's it!
1846 if (type != STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
1847 return false;
1848 }
1849
1850 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
1851 startingData = new SplashScreenStartingData(mWmService, pkg,
1852 theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
1853 getMergedOverrideConfiguration());
1854 scheduleAddStartingWindow();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001855 return true;
1856 }
1857
1858
1859 private boolean createSnapshot(ActivityManager.TaskSnapshot snapshot) {
1860 if (snapshot == null) {
1861 return false;
1862 }
1863
1864 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001865 startingData = new SnapshotStartingData(mWmService, snapshot);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001866 scheduleAddStartingWindow();
1867 return true;
1868 }
1869
1870 void scheduleAddStartingWindow() {
1871 // Note: we really want to do sendMessageAtFrontOfQueue() because we
1872 // want to process the message ASAP, before any other queued
1873 // messages.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001874 if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001875 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001876 mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001877 }
1878 }
1879
1880 private final Runnable mAddStartingWindow = new Runnable() {
1881
1882 @Override
1883 public void run() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001884 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001885 // There can only be one adding request, silly caller!
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001886 mWmService.mAnimationHandler.removeCallbacks(this);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001887 }
1888
1889 if (startingData == null) {
1890 // Animation has been canceled... do nothing.
1891 if (DEBUG_STARTING_WINDOW) {
1892 Slog.v(TAG, "startingData was nulled out before handling"
1893 + " mAddStartingWindow: " + AppWindowToken.this);
1894 }
1895 return;
1896 }
1897
1898 if (DEBUG_STARTING_WINDOW) {
1899 Slog.v(TAG, "Add starting " + this + ": startingData=" + startingData);
1900 }
1901
1902 WindowManagerPolicy.StartingSurface surface = null;
1903 try {
1904 surface = startingData.createStartingSurface(AppWindowToken.this);
1905 } catch (Exception e) {
1906 Slog.w(TAG, "Exception when adding starting window", e);
1907 }
1908 if (surface != null) {
1909 boolean abort = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001910 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001911 // If the window was successfully added, then
1912 // we need to remove it.
1913 if (removed || startingData == null) {
1914 if (DEBUG_STARTING_WINDOW) {
1915 Slog.v(TAG, "Aborted starting " + AppWindowToken.this
1916 + ": removed=" + removed + " startingData=" + startingData);
1917 }
1918 startingWindow = null;
1919 startingData = null;
1920 abort = true;
1921 } else {
1922 startingSurface = surface;
1923 }
1924 if (DEBUG_STARTING_WINDOW && !abort) {
1925 Slog.v(TAG, "Added starting " + AppWindowToken.this + ": startingWindow="
1926 + startingWindow + " startingView=" + startingSurface);
1927 }
1928 }
1929 if (abort) {
1930 surface.remove();
1931 }
1932 } else if (DEBUG_STARTING_WINDOW) {
1933 Slog.v(TAG, "Surface returned was null: " + AppWindowToken.this);
1934 }
1935 }
1936 };
1937
1938 private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
1939 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
1940 ActivityManager.TaskSnapshot snapshot) {
1941 if (getDisplayContent().mAppTransition.getAppTransition()
1942 == TRANSIT_DOCK_TASK_FROM_RECENTS) {
1943 // TODO(b/34099271): Remove this statement to add back the starting window and figure
1944 // out why it causes flickering, the starting window appears over the thumbnail while
1945 // the docked from recents transition occurs
1946 return STARTING_WINDOW_TYPE_NONE;
1947 } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
1948 return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1949 } else if (taskSwitch && allowTaskSnapshot) {
Kevin58b47f12018-12-17 14:09:01 -08001950 if (mWmService.mLowRamTaskSnapshots) {
1951 // For low RAM devices, we use the splash screen starting window instead of the
1952 // task snapshot starting window.
1953 return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1954 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001955 return snapshot == null ? STARTING_WINDOW_TYPE_NONE
1956 : snapshotOrientationSameAsTask(snapshot) || fromRecents
1957 ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1958 } else {
1959 return STARTING_WINDOW_TYPE_NONE;
1960 }
1961 }
1962
1963
1964 private boolean snapshotOrientationSameAsTask(ActivityManager.TaskSnapshot snapshot) {
1965 if (snapshot == null) {
1966 return false;
1967 }
1968 return getTask().getConfiguration().orientation == snapshot.getOrientation();
1969 }
1970
1971 void removeStartingWindow() {
1972 if (startingWindow == null) {
1973 if (startingData != null) {
1974 // Starting window has not been added yet, but it is scheduled to be added.
1975 // Go ahead and cancel the request.
1976 if (DEBUG_STARTING_WINDOW) {
1977 Slog.v(TAG_WM, "Clearing startingData for token=" + this);
1978 }
1979 startingData = null;
1980 }
1981 return;
1982 }
1983
1984 final WindowManagerPolicy.StartingSurface surface;
1985 if (startingData != null) {
1986 surface = startingSurface;
1987 startingData = null;
1988 startingSurface = null;
1989 startingWindow = null;
1990 startingDisplayed = false;
1991 if (surface == null) {
1992 if (DEBUG_STARTING_WINDOW) {
1993 Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
1994 + "remove");
1995 }
1996 return;
1997 }
1998 } else {
1999 if (DEBUG_STARTING_WINDOW) {
2000 Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
2001 + this);
2002 }
2003 return;
2004 }
2005
2006 if (DEBUG_STARTING_WINDOW) {
2007 Slog.v(TAG_WM, "Schedule remove starting " + this
2008 + " startingWindow=" + startingWindow
2009 + " startingView=" + startingSurface
2010 + " Callers=" + Debug.getCallers(5));
2011 }
2012
2013 // Use the same thread to remove the window as we used to add it, as otherwise we end up
2014 // with things in the view hierarchy being called from different threads.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002015 mWmService.mAnimationHandler.post(() -> {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002016 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
2017 try {
2018 surface.remove();
2019 } catch (Exception e) {
2020 Slog.w(TAG_WM, "Exception when removing starting window", e);
2021 }
2022 });
2023 }
2024
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07002025 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07002026 boolean fillsParent() {
2027 return mFillsParent;
2028 }
2029
2030 void setFillsParent(boolean fillsParent) {
2031 mFillsParent = fillsParent;
2032 }
2033
Jorim Jaggife762342016-10-13 14:33:27 +02002034 boolean containsDismissKeyguardWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002035 // Window state is transient during relaunch. We are not guaranteed to be frozen during the
2036 // entirety of the relaunch.
2037 if (isRelaunching()) {
2038 return mLastContainsDismissKeyguardWindow;
2039 }
2040
Jorim Jaggife762342016-10-13 14:33:27 +02002041 for (int i = mChildren.size() - 1; i >= 0; i--) {
2042 if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
2043 return true;
2044 }
2045 }
2046 return false;
2047 }
2048
2049 boolean containsShowWhenLockedWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002050 // When we are relaunching, it is possible for us to be unfrozen before our previous
2051 // windows have been added back. Using the cached value ensures that our previous
2052 // showWhenLocked preference is honored until relaunching is complete.
2053 if (isRelaunching()) {
2054 return mLastContainsShowWhenLockedWindow;
2055 }
2056
Jorim Jaggife762342016-10-13 14:33:27 +02002057 for (int i = mChildren.size() - 1; i >= 0; i--) {
2058 if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
2059 return true;
2060 }
2061 }
Bryce Lee081554b2017-05-25 07:52:12 -07002062
Jorim Jaggife762342016-10-13 14:33:27 +02002063 return false;
2064 }
2065
2066 void checkKeyguardFlagsChanged() {
2067 final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
2068 final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
2069 if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
2070 || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002071 mWmService.notifyKeyguardFlagsChanged(null /* callback */,
lumark588a3e82018-07-20 18:53:54 +08002072 getDisplayContent().getDisplayId());
Jorim Jaggife762342016-10-13 14:33:27 +02002073 }
2074 mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
2075 mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
2076 }
2077
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002078 WindowState getImeTargetBelowWindow(WindowState w) {
2079 final int index = mChildren.indexOf(w);
2080 if (index > 0) {
2081 final WindowState target = mChildren.get(index - 1);
2082 if (target.canBeImeTarget()) {
2083 return target;
2084 }
2085 }
2086 return null;
2087 }
2088
2089 WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
2090 WindowState candidate = null;
2091 for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
2092 final WindowState w = mChildren.get(i);
2093 if (w.mRemoved) {
2094 continue;
2095 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02002096 if (candidate == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002097 candidate = w;
2098 }
2099 }
2100 return candidate;
2101 }
2102
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002103 /**
2104 * See {@link Activity#setDisablePreviewScreenshots}.
2105 */
2106 void setDisablePreviewScreenshots(boolean disable) {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002107 mDisablePreviewScreenshots = disable;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002108 }
2109
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002110 /**
chaviwd3bf08d2017-08-01 17:24:59 -07002111 * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
2112 */
2113 void setCanTurnScreenOn(boolean canTurnScreenOn) {
2114 mCanTurnScreenOn = canTurnScreenOn;
2115 }
2116
2117 /**
2118 * Indicates whether the current launch can turn the screen on. This is to prevent multiple
2119 * relayouts from turning the screen back on. The screen should only turn on at most
2120 * once per activity resume.
2121 *
2122 * @return true if the screen can be turned on.
2123 */
2124 boolean canTurnScreenOn() {
2125 return mCanTurnScreenOn;
2126 }
2127
2128 /**
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002129 * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
2130 * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
2131 * we can't take a snapshot for other reasons, for example, if we have a secure window.
2132 *
2133 * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
2134 * screenshot.
2135 */
2136 boolean shouldUseAppThemeSnapshot() {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002137 return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002138 true /* topToBottom */);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002139 }
2140
Jorim Jaggibe418292018-03-26 16:14:12 +02002141 SurfaceControl getAppAnimationLayer() {
Jorim Jaggi391790622018-04-18 15:30:44 +02002142 return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
2143 : needsZBoost() ? ANIMATION_LAYER_BOOSTED
2144 : ANIMATION_LAYER_STANDARD);
Jorim Jaggibe418292018-03-26 16:14:12 +02002145 }
2146
chaviw23ee71c2017-12-18 11:29:41 -08002147 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +01002148 public SurfaceControl getAnimationLeashParent() {
Robert Carrb9506032018-02-13 13:54:00 -08002149 // All normal app transitions take place in an animation layer which is below the pinned
2150 // stack but may be above the parent stacks of the given animating apps.
2151 // For transitions in the pinned stack (menu activity) we just let them occur as a child
2152 // of the pinned stack.
2153 if (!inPinnedWindowingMode()) {
2154 return getAppAnimationLayer();
2155 } else {
2156 return getStack().getSurfaceControl();
2157 }
chaviw23ee71c2017-12-18 11:29:41 -08002158 }
2159
Jorim Jaggic6976f02018-04-18 16:31:07 +02002160 private boolean shouldAnimate(int transit) {
2161 final boolean isSplitScreenPrimary =
2162 getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
2163 final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
2164
2165 // We animate always if it's not split screen primary, and only some special cases in split
2166 // screen primary because it causes issues with stack clipping when we run an un-minimize
2167 // animation at the same time.
2168 return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
2169 }
2170
Vishnu Naira2977262018-07-26 13:31:26 -07002171 /**
2172 * Creates a layer to apply crop to an animation.
2173 */
2174 private SurfaceControl createAnimationBoundsLayer(Transaction t) {
2175 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
2176 final SurfaceControl.Builder builder = makeAnimationLeash()
2177 .setParent(getAnimationLeashParent())
Vishnu Naire86bd982018-11-28 13:23:17 -08002178 .setName(getSurfaceControl() + " - animation-bounds");
Vishnu Naira2977262018-07-26 13:31:26 -07002179 final SurfaceControl boundsLayer = builder.build();
2180 t.show(boundsLayer);
2181 return boundsLayer;
2182 }
2183
Riddle Hsua118b3a2018-10-11 22:05:06 +08002184 /** Get position and crop region of animation. */
2185 @VisibleForTesting
2186 void getAnimationBounds(Point outPosition, Rect outBounds) {
2187 outPosition.set(0, 0);
2188 outBounds.setEmpty();
2189
2190 final TaskStack stack = getStack();
2191 final Task task = getTask();
2192 if (task != null && task.inFreeformWindowingMode()) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002193 task.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002194 } else if (stack != null) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002195 stack.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002196 }
2197
2198 // Always use stack bounds in order to have the ability to animate outside the task region.
2199 // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
2200 // according to the bounds.
2201 if (stack != null) {
2202 stack.getBounds(outBounds);
2203 }
2204 // We have the relative position so the local position can be removed from bounds.
2205 outBounds.offsetTo(0, 0);
2206 }
2207
Evan Roskyed6767f2018-10-26 17:21:06 -07002208 @Override
2209 Rect getDisplayedBounds() {
2210 final Task task = getTask();
2211 if (task != null) {
2212 final Rect overrideDisplayedBounds = task.getOverrideDisplayedBounds();
2213 if (!overrideDisplayedBounds.isEmpty()) {
2214 return overrideDisplayedBounds;
2215 }
2216 }
2217 return getBounds();
2218 }
2219
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002220 boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
2221 boolean isVoiceInteraction) {
2222
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002223 if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002224 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Jorim Jaggic6976f02018-04-18 16:31:07 +02002225 Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
2226 + " atoken=" + this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002227 }
2228 cancelAnimation();
2229 return false;
2230 }
2231
2232 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
2233 // to animate and it can cause strange artifacts when we unfreeze the display if some
2234 // different animation is running.
2235 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
2236 if (okToAnimate()) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002237 final AnimationAdapter adapter;
Riddle Hsua118b3a2018-10-11 22:05:06 +08002238 getAnimationBounds(mTmpPoint, mTmpRect);
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002239
2240 // Delaying animation start isn't compatible with remote animations at all.
lumark588a3e82018-07-20 18:53:54 +08002241 if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002242 && !mSurfaceAnimator.isAnimationStartDelayed()) {
lumark588a3e82018-07-20 18:53:54 +08002243 adapter = getDisplayContent().mAppTransition.getRemoteAnimationController()
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002244 .createAnimationAdapter(this, mTmpPoint, mTmpRect);
2245 } else {
lumark588a3e82018-07-20 18:53:54 +08002246 final int appStackClipMode =
2247 getDisplayContent().mAppTransition.getAppStackClipMode();
Vishnu Naira2977262018-07-26 13:31:26 -07002248 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
2249
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002250 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
2251 if (a != null) {
2252 adapter = new LocalAnimationAdapter(
2253 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
lumark588a3e82018-07-20 18:53:54 +08002254 getDisplayContent().mAppTransition.canSkipFirstFrame(),
Vishnu Naira2977262018-07-26 13:31:26 -07002255 appStackClipMode,
Jorim Jaggiaa763cd2018-03-22 23:20:36 +01002256 true /* isAppAnimation */),
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002257 mWmService.mSurfaceAnimationRunner);
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002258 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
2259 mNeedsZBoost = true;
2260 }
2261 mTransit = transit;
lumark588a3e82018-07-20 18:53:54 +08002262 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002263 } else {
2264 adapter = null;
chaviw23ee71c2017-12-18 11:29:41 -08002265 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002266 }
2267 if (adapter != null) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002268 startAnimation(getPendingTransaction(), adapter, !isVisible());
Jorim Jaggi82c17862018-02-21 17:50:18 +01002269 if (adapter.getShowWallpaper()) {
2270 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2271 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002272 }
2273 } else {
2274 cancelAnimation();
2275 }
2276 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2277
2278 return isReallyAnimating();
2279 }
2280
2281 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
2282 boolean isVoiceInteraction) {
2283 final DisplayContent displayContent = getTask().getDisplayContent();
2284 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2285 final int width = displayInfo.appWidth;
2286 final int height = displayInfo.appHeight;
2287 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
2288 "applyAnimation: atoken=" + this);
2289
2290 // Determine the visible rect to calculate the thumbnail clip
2291 final WindowState win = findMainWindow();
2292 final Rect frame = new Rect(0, 0, width, height);
2293 final Rect displayFrame = new Rect(0, 0,
2294 displayInfo.logicalWidth, displayInfo.logicalHeight);
2295 final Rect insets = new Rect();
2296 final Rect stableInsets = new Rect();
2297 Rect surfaceInsets = null;
2298 final boolean freeform = win != null && win.inFreeformWindowingMode();
2299 if (win != null) {
2300 // Containing frame will usually cover the whole screen, including dialog windows.
2301 // For freeform workspace windows it will not cover the whole screen and it also
2302 // won't exactly match the final freeform window frame (e.g. when overlapping with
2303 // the status bar). In that case we need to use the final frame.
2304 if (freeform) {
chaviw492139a2018-07-16 16:07:35 -07002305 frame.set(win.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01002306 } else if (win.isLetterboxedAppWindow()) {
2307 frame.set(getTask().getBounds());
Winson Chungc1674272018-02-21 10:15:17 -08002308 } else if (win.isDockedResizing()) {
2309 // If we are animating while docked resizing, then use the stack bounds as the
2310 // animation target (which will be different than the task bounds)
2311 frame.set(getTask().getParent().getBounds());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002312 } else {
chaviw553b0212018-07-12 13:37:01 -07002313 frame.set(win.getContainingFrame());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002314 }
2315 surfaceInsets = win.getAttrs().surfaceInsets;
Adrian Roos20e07892018-02-23 19:12:01 +01002316 // XXX(b/72757033): These are insets relative to the window frame, but we're really
2317 // interested in the insets relative to the frame we chose in the if-blocks above.
chaviw9c81e632018-07-31 11:17:52 -07002318 win.getContentInsets(insets);
2319 win.getStableInsets(stableInsets);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002320 }
2321
2322 if (mLaunchTaskBehind) {
2323 // Differentiate the two animations. This one which is briefly on the screen
2324 // gets the !enter animation, and the other activity which remains on the
2325 // screen gets the enter animation. Both appear in the mOpeningApps set.
2326 enter = false;
2327 }
2328 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
2329 + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
2330 + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
2331 final Configuration displayConfig = displayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002332 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002333 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
2334 surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
2335 if (a != null) {
2336 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
2337 final int containingWidth = frame.width();
2338 final int containingHeight = frame.height();
2339 a.initialize(containingWidth, containingHeight, width, height);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002340 a.scaleCurrentDuration(mWmService.getTransitionAnimationScaleLocked());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002341 }
2342 return a;
2343 }
2344
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002345 @Override
Jorim Jaggi6de61012018-03-19 14:53:23 +01002346 public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
2347 return mAnimatingAppWindowTokenRegistry != null
2348 && mAnimatingAppWindowTokenRegistry.notifyAboutToFinish(
2349 this, endDeferFinishCallback);
2350 }
2351
2352 @Override
2353 public void onAnimationLeashDestroyed(Transaction t) {
2354 super.onAnimationLeashDestroyed(t);
Vishnu Naira2977262018-07-26 13:31:26 -07002355 if (mAnimationBoundsLayer != null) {
Robert Carr8810b692018-12-11 15:49:48 -08002356 t.reparent(mAnimationBoundsLayer, null);
Vishnu Naira2977262018-07-26 13:31:26 -07002357 mAnimationBoundsLayer = null;
2358 }
2359
Jorim Jaggi6de61012018-03-19 14:53:23 +01002360 if (mAnimatingAppWindowTokenRegistry != null) {
2361 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
2362 }
2363 }
2364
2365 @Override
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002366 protected void setLayer(Transaction t, int layer) {
2367 if (!mSurfaceAnimator.hasLeash()) {
2368 t.setLayer(mSurfaceControl, layer);
2369 }
2370 }
2371
2372 @Override
2373 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
2374 if (!mSurfaceAnimator.hasLeash()) {
2375 t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
2376 }
2377 }
2378
2379 @Override
2380 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
2381 if (!mSurfaceAnimator.hasLeash()) {
2382 t.reparent(mSurfaceControl, newParent.getHandle());
2383 }
2384 }
2385
2386 @Override
2387 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002388 // The leash is parented to the animation layer. We need to preserve the z-order by using
2389 // the prefix order index, but we boost if necessary.
Robert Carrb9506032018-02-13 13:54:00 -08002390 int layer = 0;
2391 if (!inPinnedWindowingMode()) {
2392 layer = getPrefixOrderIndex();
2393 } else {
2394 // Pinned stacks have animations take place within themselves rather than an animation
2395 // layer so we need to preserve the order relative to the stack (e.g. the order of our
2396 // task/parent).
2397 layer = getParent().getPrefixOrderIndex();
2398 }
2399
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002400 if (mNeedsZBoost) {
2401 layer += Z_BOOST_BASE;
2402 }
2403 leash.setLayer(layer);
Robert Carr2f8aa392018-01-31 14:46:51 -08002404
2405 final DisplayContent dc = getDisplayContent();
Jorim Jaggibe418292018-03-26 16:14:12 +02002406 dc.assignStackOrdering();
Jorim Jaggi6de61012018-03-19 14:53:23 +01002407 if (mAnimatingAppWindowTokenRegistry != null) {
2408 mAnimatingAppWindowTokenRegistry.notifyStarting(this);
2409 }
Vishnu Naira2977262018-07-26 13:31:26 -07002410
2411 // If the animation needs to be cropped then an animation bounds layer is created as a child
2412 // of the pinned stack or animation layer. The leash is then reparented to this new layer.
2413 if (mNeedsAnimationBoundsLayer) {
2414 final TaskStack stack = getStack();
2415 if (stack == null) {
2416 return;
2417 }
2418 mAnimationBoundsLayer = createAnimationBoundsLayer(t);
2419
2420 // Set clip rect to stack bounds.
2421 mTmpRect.setEmpty();
2422 stack.getBounds(mTmpRect);
2423
2424 // Crop to stack bounds.
2425 t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
2426
2427 // Reparent leash to animation bounds layer.
2428 t.reparent(leash, mAnimationBoundsLayer.getHandle());
2429 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002430 }
2431
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002432 /**
2433 * This must be called while inside a transaction.
2434 */
2435 void showAllWindowsLocked() {
2436 forAllWindows(windowState -> {
2437 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + windowState);
2438 windowState.performShowLocked();
2439 }, false /* traverseTopToBottom */);
Jorim Jaggia5e10572017-11-15 14:36:26 +01002440 }
2441
2442 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002443 protected void onAnimationFinished() {
2444 super.onAnimationFinished();
2445
2446 mTransit = TRANSIT_UNSET;
2447 mTransitFlags = 0;
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002448 mNeedsZBoost = false;
Vishnu Naira2977262018-07-26 13:31:26 -07002449 mNeedsAnimationBoundsLayer = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002450
2451 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
2452 "AppWindowToken");
2453
Jorim Jaggi988f6682017-11-17 17:46:43 +01002454 clearThumbnail();
Jorim Jaggi752cd822018-03-29 16:29:18 +02002455 setClientHidden(isHidden() && hiddenRequested);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002456
lumarkff0ab692018-11-05 20:32:30 +08002457 getDisplayContent().computeImeTargetIfNeeded(this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002458
2459 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this
2460 + ": reportedVisible=" + reportedVisible
2461 + " okToDisplay=" + okToDisplay()
2462 + " okToAnimate=" + okToAnimate()
2463 + " startingDisplayed=" + startingDisplayed);
2464
2465 // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
2466 // traverse the copy.
2467 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
2468 children.forEach(WindowState::onExitAnimationDone);
2469
lumark588a3e82018-07-20 18:53:54 +08002470 getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002471 scheduleAnimation();
2472 }
2473
2474 @Override
2475 boolean isAppAnimating() {
2476 return isSelfAnimating();
2477 }
2478
2479 @Override
2480 boolean isSelfAnimating() {
2481 // If we are about to start a transition, we also need to be considered animating.
2482 return isWaitingForTransitionStart() || isReallyAnimating();
2483 }
2484
2485 /**
2486 * @return True if and only if we are actually running an animation. Note that
2487 * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
2488 * start.
2489 */
2490 private boolean isReallyAnimating() {
2491 return super.isSelfAnimating();
2492 }
2493
Jorim Jaggi988f6682017-11-17 17:46:43 +01002494 @Override
2495 void cancelAnimation() {
2496 super.cancelAnimation();
2497 clearThumbnail();
2498 }
2499
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002500 boolean isWaitingForTransitionStart() {
lumark588a3e82018-07-20 18:53:54 +08002501 return getDisplayContent().mAppTransition.isTransitionSet()
2502 && (getDisplayContent().mOpeningApps.contains(this)
2503 || getDisplayContent().mClosingApps.contains(this));
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002504 }
2505
2506 public int getTransit() {
2507 return mTransit;
2508 }
2509
2510 int getTransitFlags() {
2511 return mTransitFlags;
2512 }
2513
Jorim Jaggi988f6682017-11-17 17:46:43 +01002514 void attachThumbnailAnimation() {
2515 if (!isReallyAnimating()) {
2516 return;
2517 }
2518 final int taskId = getTask().mTaskId;
2519 final GraphicBuffer thumbnailHeader =
lumark588a3e82018-07-20 18:53:54 +08002520 getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002521 if (thumbnailHeader == null) {
2522 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
2523 return;
2524 }
2525 clearThumbnail();
2526 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
2527 mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
2528 }
2529
Tony Mak64b8d562017-12-28 17:44:02 +00002530 /**
2531 * Attaches a surface with a thumbnail for the
2532 * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
2533 */
2534 void attachCrossProfileAppsThumbnailAnimation() {
2535 if (!isReallyAnimating()) {
2536 return;
2537 }
2538 clearThumbnail();
2539
2540 final WindowState win = findMainWindow();
2541 if (win == null) {
2542 return;
2543 }
chaviw492139a2018-07-16 16:07:35 -07002544 final Rect frame = win.getFrameLw();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002545 final int thumbnailDrawableRes = getTask().mUserId == mWmService.mCurrentUserId
Tony Mak64b8d562017-12-28 17:44:02 +00002546 ? R.drawable.ic_account_circle
Tony Makda4af232018-04-27 11:01:10 +01002547 : R.drawable.ic_corp_badge;
Tony Mak64b8d562017-12-28 17:44:02 +00002548 final GraphicBuffer thumbnail =
lumark588a3e82018-07-20 18:53:54 +08002549 getDisplayContent().mAppTransition
Tony Mak64b8d562017-12-28 17:44:02 +00002550 .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
2551 if (thumbnail == null) {
2552 return;
2553 }
2554 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
2555 final Animation animation =
lumark588a3e82018-07-20 18:53:54 +08002556 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
chaviw492139a2018-07-16 16:07:35 -07002557 win.getFrameLw());
Tony Mak64b8d562017-12-28 17:44:02 +00002558 mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
2559 frame.top));
2560 }
2561
Jorim Jaggi988f6682017-11-17 17:46:43 +01002562 private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
2563 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
2564
2565 // If this is a multi-window scenario, we use the windows frame as
2566 // destination of the thumbnail header animation. If this is a full screen
2567 // window scenario, we use the whole display as the target.
2568 WindowState win = findMainWindow();
2569 Rect appRect = win != null ? win.getContentFrameLw() :
2570 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
chaviw9c81e632018-07-31 11:17:52 -07002571 final Rect insets = win != null ? win.getContentInsets() : null;
Jorim Jaggi988f6682017-11-17 17:46:43 +01002572 final Configuration displayConfig = mDisplayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002573 return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
Jorim Jaggi988f6682017-11-17 17:46:43 +01002574 appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
2575 displayConfig.orientation);
2576 }
2577
2578 private void clearThumbnail() {
2579 if (mThumbnail == null) {
2580 return;
2581 }
2582 mThumbnail.destroy();
2583 mThumbnail = null;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002584 }
2585
Jorim Jaggif84e2f62018-01-16 14:17:59 +01002586 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
2587 mRemoteAnimationDefinition = definition;
2588 }
2589
2590 RemoteAnimationDefinition getRemoteAnimationDefinition() {
2591 return mRemoteAnimationDefinition;
2592 }
2593
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002594 @Override
2595 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2596 super.dump(pw, prefix, dumpAll);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002597 if (appToken != null) {
Wale Ogunwale72919d22016-12-08 18:58:50 -08002598 pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002599 }
Winson Chung48b25652018-10-22 14:04:30 -07002600 pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08002601 pw.print(prefix); pw.print("task="); pw.println(getTask());
Wale Ogunwale51362492016-09-08 17:49:17 -07002602 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
2603 pw.print(" mOrientation="); pw.println(mOrientation);
Wale Ogunwale89973222017-04-23 18:39:45 -07002604 pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
2605 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
2606 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07002607 if (paused) {
2608 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002609 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08002610 if (mAppStopped) {
2611 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
2612 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002613 if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002614 || allDrawn || mLastAllDrawn) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002615 pw.print(prefix); pw.print("mNumInterestingWindows=");
2616 pw.print(mNumInterestingWindows);
2617 pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002618 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07002619 pw.print(" allDrawn="); pw.print(allDrawn);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002620 pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
Craig Mautner6fbda632012-07-03 09:26:39 -07002621 pw.println(")");
2622 }
2623 if (inPendingTransaction) {
2624 pw.print(prefix); pw.print("inPendingTransaction=");
2625 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002626 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08002627 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002628 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
2629 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08002630 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08002631 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002632 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002633 if (startingWindow != null || startingSurface != null
Wale Ogunwale6c459212017-05-17 08:56:03 -07002634 || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002635 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002636 pw.print(" startingSurface="); pw.print(startingSurface);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002637 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale6c459212017-05-17 08:56:03 -07002638 pw.print(" startingMoved="); pw.print(startingMoved);
2639 pw.println(" mHiddenSetFromTransferredStartingWindow="
2640 + mHiddenSetFromTransferredStartingWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002641 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01002642 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08002643 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002644 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08002645 }
2646 if (mPendingRelaunchCount != 0) {
2647 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01002648 }
Wale Ogunwalee287e192017-04-21 09:30:12 -07002649 if (mRemovingFromDisplay) {
2650 pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
2651 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002652 }
2653
2654 @Override
2655 void setHidden(boolean hidden) {
2656 super.setHidden(hidden);
Winson Chunge55c0192017-08-24 14:50:48 -07002657
2658 if (hidden) {
2659 // Once the app window is hidden, reset the last saved PiP snap fraction
2660 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
2661 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002662 scheduleAnimation();
2663 }
2664
2665 @Override
2666 void prepareSurfaces() {
2667 // isSelfAnimating also returns true when we are about to start a transition, so we need
2668 // to check super here.
2669 final boolean reallyAnimating = super.isSelfAnimating();
2670 final boolean show = !isHidden() || reallyAnimating;
2671 if (show && !mLastSurfaceShowing) {
2672 mPendingTransaction.show(mSurfaceControl);
2673 } else if (!show && mLastSurfaceShowing) {
2674 mPendingTransaction.hide(mSurfaceControl);
Jorim Jaggi4d1835d2017-08-31 17:28:27 +02002675 }
Jorim Jaggi988f6682017-11-17 17:46:43 +01002676 if (mThumbnail != null) {
2677 mThumbnail.setShowing(mPendingTransaction, show);
2678 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002679 mLastSurfaceShowing = show;
2680 super.prepareSurfaces();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002681 }
2682
Jorim Jaggi77d0f36c2018-03-16 17:49:49 +01002683 /**
2684 * @return Whether our {@link #getSurfaceControl} is currently showing.
2685 */
2686 boolean isSurfaceShowing() {
2687 return mLastSurfaceShowing;
2688 }
2689
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002690 boolean isFreezingScreen() {
2691 return mFreezingScreen;
2692 }
2693
2694 @Override
2695 boolean needsZBoost() {
2696 return mNeedsZBoost || super.needsZBoost();
2697 }
2698
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07002699 @CallSuper
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002700 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02002701 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07002702 final long token = proto.start(fieldId);
2703 writeNameToProto(proto, NAME);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002704 super.writeToProto(proto, WINDOW_TOKEN, trim);
Vishnu Nair04ab4392018-01-10 11:00:06 -08002705 proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
2706 proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
2707 proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
2708 if (mThumbnail != null){
2709 mThumbnail.writeToProto(proto, THUMBNAIL);
2710 }
2711 proto.write(FILLS_PARENT, mFillsParent);
2712 proto.write(APP_STOPPED, mAppStopped);
2713 proto.write(HIDDEN_REQUESTED, hiddenRequested);
2714 proto.write(CLIENT_HIDDEN, mClientHidden);
2715 proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
2716 proto.write(REPORTED_DRAWN, reportedDrawn);
2717 proto.write(REPORTED_VISIBLE, reportedVisible);
2718 proto.write(NUM_INTERESTING_WINDOWS, mNumInterestingWindows);
2719 proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
2720 proto.write(ALL_DRAWN, allDrawn);
2721 proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
2722 proto.write(REMOVED, removed);
2723 if (startingWindow != null){
2724 startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
2725 }
2726 proto.write(STARTING_DISPLAYED, startingDisplayed);
2727 proto.write(STARTING_MOVED, startingMoved);
2728 proto.write(HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW,
2729 mHiddenSetFromTransferredStartingWindow);
2730 for (Rect bounds : mFrozenBounds) {
2731 bounds.writeToProto(proto, FROZEN_BOUNDS);
2732 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002733 proto.end(token);
2734 }
2735
2736 void writeNameToProto(ProtoOutputStream proto, long fieldId) {
2737 if (appToken == null) {
2738 return;
2739 }
2740 try {
2741 proto.write(fieldId, appToken.getName());
2742 } catch (RemoteException e) {
2743 // This shouldn't happen, but in this case fall back to outputting nothing
2744 Slog.e(TAG, e.toString());
2745 }
2746 }
2747
2748 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002749 public String toString() {
2750 if (stringName == null) {
2751 StringBuilder sb = new StringBuilder();
2752 sb.append("AppWindowToken{");
2753 sb.append(Integer.toHexString(System.identityHashCode(this)));
2754 sb.append(" token="); sb.append(token); sb.append('}');
2755 stringName = sb.toString();
2756 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002757 return stringName + ((mIsExiting) ? " mIsExiting=" : "");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002758 }
Adrian Roos20e07892018-02-23 19:12:01 +01002759
2760 Rect getLetterboxInsets() {
2761 if (mLetterbox != null) {
2762 return mLetterbox.getInsets();
2763 } else {
2764 return new Rect();
2765 }
2766 }
Adrian Roos23df3a32018-03-15 15:41:13 +01002767
2768 /**
2769 * @eturn true if there is a letterbox and any part of that letterbox overlaps with
2770 * the given {@code rect}.
2771 */
2772 boolean isLetterboxOverlappingWith(Rect rect) {
2773 return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
2774 }
chaviw4ad54912018-05-30 11:05:44 -07002775
2776 /**
2777 * Sets if this AWT is in the process of closing or entering PIP.
2778 * {@link #mWillCloseOrEnterPip}}
2779 */
2780 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
2781 mWillCloseOrEnterPip = willCloseOrEnterPip;
2782 }
2783
2784 /**
2785 * Returns whether this AWT is considered closing. Conditions are either
2786 * 1. Is this app animating and was requested to be hidden
2787 * 2. App is delayed closing since it might enter PIP.
2788 */
2789 boolean isClosingOrEnteringPip() {
2790 return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
2791 }
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +02002792
2793 /**
2794 * @return Whether we are allowed to show non-starting windows at the moment. We disallow
2795 * showing windows during transitions in case we have windows that have wide-color-gamut
2796 * color mode set to avoid jank in the middle of the transition.
2797 */
2798 boolean canShowWindows() {
2799 return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
2800 }
2801
2802 /**
2803 * @return true if we have a window that has a non-default color mode set; false otherwise.
2804 */
2805 private boolean hasNonDefaultColorWindow() {
2806 return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
2807 true /* topToBottom */);
2808 }
lumark588a3e82018-07-20 18:53:54 +08002809
2810 void removeFromPendingTransition() {
2811 if (isWaitingForTransitionStart() && mDisplayContent != null) {
2812 mDisplayContent.mOpeningApps.remove(this);
2813 mDisplayContent.mClosingApps.remove(this);
2814 }
2815 }
Jeff Browne9bdb312012-04-05 15:30:10 -07002816}