blob: 780eda49faf46f494f4a432615de777feea5454c [file] [log] [blame]
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wm;
18
Winson Chunge55c0192017-08-24 14:50:48 -070019import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
Jorim Jaggic6976f02018-04-18 16:31:07 +020020import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
Winson Chunge55c0192017-08-24 14:50:48 -070021import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +020022import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
Wale Ogunwale72919d22016-12-08 18:58:50 -080023import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
24import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -070025import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
Wale Ogunwale51362492016-09-08 17:49:17 -070026import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020027import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070028import static android.view.Display.DEFAULT_DISPLAY;
Jorim Jaggife762342016-10-13 14:33:27 +020029import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020030import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080031import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020032import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070033import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080034import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070035import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080036import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
chaviw9c81e632018-07-31 11:17:52 -070037import static android.view.WindowManager.TRANSIT_UNSET;
Jorim Jaggic6976f02018-04-18 16:31:07 +020038import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
chaviw9c81e632018-07-31 11:17:52 -070039
Adrian Roose99bc052017-11-20 17:55:31 +010040import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
41import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070042import static com.android.server.wm.AppWindowTokenProto.ALL_DRAWN;
43import static com.android.server.wm.AppWindowTokenProto.APP_STOPPED;
44import static com.android.server.wm.AppWindowTokenProto.CLIENT_HIDDEN;
45import static com.android.server.wm.AppWindowTokenProto.DEFER_HIDING_CLIENT;
46import static com.android.server.wm.AppWindowTokenProto.FILLS_PARENT;
47import static com.android.server.wm.AppWindowTokenProto.FROZEN_BOUNDS;
48import static com.android.server.wm.AppWindowTokenProto.HIDDEN_REQUESTED;
49import static com.android.server.wm.AppWindowTokenProto.HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW;
50import static com.android.server.wm.AppWindowTokenProto.IS_REALLY_ANIMATING;
51import static com.android.server.wm.AppWindowTokenProto.IS_WAITING_FOR_TRANSITION_START;
52import static com.android.server.wm.AppWindowTokenProto.LAST_ALL_DRAWN;
53import static com.android.server.wm.AppWindowTokenProto.LAST_SURFACE_SHOWING;
54import static com.android.server.wm.AppWindowTokenProto.NAME;
55import static com.android.server.wm.AppWindowTokenProto.NUM_DRAWN_WINDOWS;
56import static com.android.server.wm.AppWindowTokenProto.NUM_INTERESTING_WINDOWS;
57import static com.android.server.wm.AppWindowTokenProto.REMOVED;
58import static com.android.server.wm.AppWindowTokenProto.REPORTED_DRAWN;
59import static com.android.server.wm.AppWindowTokenProto.REPORTED_VISIBLE;
60import static com.android.server.wm.AppWindowTokenProto.STARTING_DISPLAYED;
61import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED;
62import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
63import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
64import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
chaviw9c81e632018-07-31 11:17:52 -070065import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
67import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
68import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
69import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
70import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
71import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
72import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
73import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
74import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
75import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
76import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
77import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
78import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
79import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
80import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
81import static com.android.server.wm.WindowManagerService.logWithStack;
Vishnu Naira2977262018-07-26 13:31:26 -070082import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080083
Wale Ogunwale0d5609b2017-09-13 05:55:07 -070084import android.annotation.CallSuper;
chaviwdcf76ec2019-01-11 16:48:46 -080085import android.annotation.Size;
Jorim Jaggid635a4a2017-05-03 15:21:26 +020086import android.app.Activity;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080087import android.app.ActivityManager;
Winson Chung48b25652018-10-22 14:04:30 -070088import android.content.ComponentName;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080089import android.content.res.CompatibilityInfo;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070090import android.content.res.Configuration;
Jorim Jaggi988f6682017-11-17 17:46:43 +010091import android.graphics.GraphicBuffer;
Jorim Jaggif5f9e122017-10-24 18:21:09 +020092import android.graphics.Point;
Jorim Jaggi0429f352015-12-22 16:29:16 +010093import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070094import android.os.Binder;
Tiger Huang51c5a1d2018-12-11 20:24:51 +080095import android.os.Build;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -080096import android.os.Debug;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070097import android.os.IBinder;
Steven Timotiusaf03df62017-07-18 16:56:43 -070098import android.os.RemoteException;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -080099import android.os.SystemClock;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200100import android.os.Trace;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800101import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -0700102import android.util.proto.ProtoOutputStream;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200103import android.view.DisplayInfo;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800104import android.view.IApplicationToken;
Robert Carr788f5742018-07-30 17:46:45 -0700105import android.view.InputApplicationHandle;
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100106import android.view.RemoteAnimationDefinition;
Robert Carr6914f082017-03-20 19:04:30 -0700107import android.view.SurfaceControl;
Tony Mak64b8d562017-12-28 17:44:02 +0000108import android.view.SurfaceControl.Transaction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800109import android.view.WindowManager;
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200110import android.view.WindowManager.LayoutParams;
Tony Mak64b8d562017-12-28 17:44:02 +0000111import android.view.animation.Animation;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800112
Tony Mak64b8d562017-12-28 17:44:02 +0000113import com.android.internal.R;
Riddle Hsua118b3a2018-10-11 22:05:06 +0800114import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800115import com.android.internal.util.ToBooleanFunction;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800116import com.android.server.AttributeCache;
chaviwdcf76ec2019-01-11 16:48:46 -0800117import com.android.server.LocalServices;
118import com.android.server.display.ColorDisplayService;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800119import com.android.server.policy.WindowManagerPolicy;
Adrian Roose99bc052017-11-20 17:55:31 +0100120import com.android.server.policy.WindowManagerPolicy.StartingSurface;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800121import com.android.server.wm.WindowManagerService.H;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800122
123import java.io.PrintWriter;
chaviwdcf76ec2019-01-11 16:48:46 -0800124import java.lang.ref.WeakReference;
Jorim Jaggi0429f352015-12-22 16:29:16 +0100125import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800126import java.util.ArrayList;
lumark588a3e82018-07-20 18:53:54 +0800127import java.util.function.Consumer;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800128
129class AppTokenList extends ArrayList<AppWindowToken> {
130}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800131
132/**
133 * Version of WindowToken that is specifically for a particular application (or
134 * really activity) that is displaying windows.
135 */
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800136class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener,
137 ConfigurationContainerListener {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800138 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
139
Jorim Jaggi619c9f72017-12-19 18:04:29 +0100140 /**
141 * Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
142 */
143 private static final int Z_BOOST_BASE = 800570000;
144
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800145 // Non-null only for application tokens.
146 final IApplicationToken appToken;
Winson Chung48b25652018-10-22 14:04:30 -0700147 final ComponentName mActivityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800148 final boolean mVoiceInteraction;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700149
Wale Ogunwale51362492016-09-08 17:49:17 -0700150 /** @see WindowContainer#fillsParent() */
151 private boolean mFillsParent;
Craig Mautner4c5eb222013-11-18 12:59:05 -0800152 boolean layoutConfigChanges;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800153 boolean mShowForAllUsers;
154 int mTargetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -0700155
Bryce Lee6d410262017-02-28 15:30:17 -0800156 // Flag set while reparenting to prevent actions normally triggered by an individual parent
157 // change.
158 private boolean mReparenting;
159
Wale Ogunwalee287e192017-04-21 09:30:12 -0700160 // True if we are current in the process of removing this app token from the display
161 private boolean mRemovingFromDisplay = false;
162
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800163 // The input dispatching timeout for this application token in nanoseconds.
Wale Ogunwale72919d22016-12-08 18:58:50 -0800164 long mInputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800165
166 // These are used for determining when all windows associated with
167 // an activity have been drawn, so they can be made visible together
168 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -0700169 // initialize so that it doesn't match mTransactionSequence which is an int.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700170 private long mLastTransactionSequence = Long.MIN_VALUE;
171 private int mNumInterestingWindows;
172 private int mNumDrawnWindows;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800173 boolean inPendingTransaction;
174 boolean allDrawn;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000175 private boolean mLastAllDrawn;
176
Craig Mautner7636dfb2012-11-16 15:24:11 -0800177 // Set to true when this app creates a surface while in the middle of an animation. In that
178 // case do not clear allDrawn until the animation completes.
179 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800180
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800181 // Is this window's surface needed? This is almost like hidden, except
182 // it will sometimes be true a little earlier: when the token has
183 // been shown, but is still waiting for its app transition to execute
184 // before making its windows shown.
185 boolean hiddenRequested;
186
187 // Have we told the window clients to hide themselves?
Wale Ogunwale89973222017-04-23 18:39:45 -0700188 private boolean mClientHidden;
189
190 // If true we will defer setting mClientHidden to true and reporting to the client that it is
191 // hidden.
192 boolean mDeferHidingClient;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800193
194 // Last visibility state we reported to the app token.
195 boolean reportedVisible;
196
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700197 // Last drawn state we reported to the app token.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700198 private boolean reportedDrawn;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700199
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800200 // Set to true when the token has been removed from the window mgr.
201 boolean removed;
202
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800203 // Information about an application starting window if displayed.
204 StartingData startingData;
205 WindowState startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800206 StartingSurface startingSurface;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800207 boolean startingDisplayed;
208 boolean startingMoved;
Jorim Jaggi60f9c972018-02-01 19:21:07 +0100209
Wale Ogunwale6c459212017-05-17 08:56:03 -0700210 // True if the hidden state of this token was forced to false due to a transferred starting
211 // window.
212 private boolean mHiddenSetFromTransferredStartingWindow;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800213 boolean firstWindowDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700214 private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
215 new WindowState.UpdateReportedVisibilityResults();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800216
217 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700218 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800219
Wale Ogunwale571771c2016-08-26 13:18:50 -0700220 // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
Craig Mautner799bc1d2015-01-14 10:33:48 -0800221 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800222
Craig Mautnerbb742462014-07-07 15:28:55 -0700223 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700224 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700225
Wale Ogunwale72919d22016-12-08 18:58:50 -0800226 private boolean mAlwaysFocusable;
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800227
Robert Carre12aece2016-02-02 22:43:27 -0800228 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700229 int mRotationAnimationHint;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700230 private int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800231
Jorim Jaggife762342016-10-13 14:33:27 +0200232 private boolean mLastContainsShowWhenLockedWindow;
233 private boolean mLastContainsDismissKeyguardWindow;
234
Jorim Jaggi0429f352015-12-22 16:29:16 +0100235 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700236 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100237
Wale Ogunwale6c459212017-05-17 08:56:03 -0700238 private boolean mDisablePreviewScreenshots;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +0100239
Wale Ogunwale034a8ec2017-09-02 17:14:40 -0700240 private Task mLastParent;
Robert Carred3e83b2017-04-21 13:26:55 -0700241
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800242 // TODO: Remove after unification
243 ActivityRecord mActivityRecord;
244
chaviwd3bf08d2017-08-01 17:24:59 -0700245 /**
246 * See {@link #canTurnScreenOn()}
247 */
248 private boolean mCanTurnScreenOn = true;
249
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200250 /**
251 * If we are running an animation, this determines the transition type. Must be one of
252 * AppTransition.TRANSIT_* constants.
253 */
254 private int mTransit;
255
256 /**
257 * If we are running an animation, this determines the flags during this animation. Must be a
258 * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
259 */
260 private int mTransitFlags;
261
262 /** Whether our surface was set to be showing in the last call to {@link #prepareSurfaces} */
Jorim Jaggifd1891462017-12-29 15:41:36 +0100263 private boolean mLastSurfaceShowing = true;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200264
Jorim Jaggi988f6682017-11-17 17:46:43 +0100265 private AppWindowThumbnail mThumbnail;
266
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000267 /** Have we been asked to have this token keep the screen frozen? */
268 private boolean mFreezingScreen;
269
270 /** Whether this token should be boosted at the top of all app window tokens. */
271 private boolean mNeedsZBoost;
Adrian Roos4d18a2e2017-12-19 19:08:05 +0100272 private Letterbox mLetterbox;
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000273
chaviw23ee71c2017-12-18 11:29:41 -0800274 private final Point mTmpPoint = new Point();
chaviw23012112017-12-20 15:29:04 -0800275 private final Rect mTmpRect = new Rect();
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100276 private RemoteAnimationDefinition mRemoteAnimationDefinition;
Jorim Jaggi6de61012018-03-19 14:53:23 +0100277 private AnimatingAppWindowTokenRegistry mAnimatingAppWindowTokenRegistry;
chaviw23ee71c2017-12-18 11:29:41 -0800278
chaviw4ad54912018-05-30 11:05:44 -0700279 /**
280 * A flag to determine if this AWT is in the process of closing or entering PIP. This is needed
281 * to help AWT know that the app is in the process of closing but hasn't yet started closing on
282 * the WM side.
283 */
284 private boolean mWillCloseOrEnterPip;
285
Vishnu Naira2977262018-07-26 13:31:26 -0700286 /** Layer used to constrain the animation to a token's stack bounds. */
287 SurfaceControl mAnimationBoundsLayer;
288
289 /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
290 boolean mNeedsAnimationBoundsLayer;
291
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800292 private static final int STARTING_WINDOW_TYPE_NONE = 0;
293 private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
294 private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
295
chaviwdcf76ec2019-01-11 16:48:46 -0800296 private AppSaturationInfo mLastAppSaturationInfo;
297
298 private final ColorDisplayService.ColorTransformController mColorTransformController =
299 (matrix, translation) -> mWmService.mH.post(() -> {
300 synchronized (mWmService.mGlobalLock) {
301 if (mLastAppSaturationInfo == null) {
302 mLastAppSaturationInfo = new AppSaturationInfo();
303 }
304
305 mLastAppSaturationInfo.setSaturation(matrix, translation);
306 updateColorTransform();
307 }
308 });
309
Winson Chung48b25652018-10-22 14:04:30 -0700310 AppWindowToken(WindowManagerService service, IApplicationToken token,
311 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
312 long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
313 int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
314 boolean launchTaskBehind, boolean alwaysFocusable,
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800315 ActivityRecord activityRecord) {
Winson Chung48b25652018-10-22 14:04:30 -0700316 this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800317 // TODO: remove after unification
318 mActivityRecord = activityRecord;
319 mActivityRecord.registerConfigurationChangeListener(this);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800320 mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800321 mShowForAllUsers = showForAllUsers;
322 mTargetSdk = targetSdk;
323 mOrientation = orientation;
324 layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0;
325 mLaunchTaskBehind = launchTaskBehind;
326 mAlwaysFocusable = alwaysFocusable;
327 mRotationAnimationHint = rotationAnimationHint;
328
329 // Application tokens start out hidden.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200330 setHidden(true);
Wale Ogunwale72919d22016-12-08 18:58:50 -0800331 hiddenRequested = true;
chaviwdcf76ec2019-01-11 16:48:46 -0800332
333 ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(
334 ColorDisplayService.ColorDisplayServiceInternal.class);
335 cds.attachColorTransformController(activityRecord.packageName, activityRecord.mUserId,
336 new WeakReference<>(mColorTransformController));
Wale Ogunwale72919d22016-12-08 18:58:50 -0800337 }
338
Winson Chung48b25652018-10-22 14:04:30 -0700339 AppWindowToken(WindowManagerService service, IApplicationToken token,
340 ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
341 boolean fillsParent) {
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800342 super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
343 false /* ownerCanManageAppTokens */);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700344 appToken = token;
Winson Chung48b25652018-10-22 14:04:30 -0700345 mActivityComponent = activityComponent;
Wale Ogunwale72919d22016-12-08 18:58:50 -0800346 mVoiceInteraction = voiceInteraction;
Wale Ogunwale17f175c2017-02-07 16:54:10 -0800347 mFillsParent = fillsParent;
Robert Carr0bcbe642018-10-11 19:07:43 -0700348 mInputApplicationHandle = new InputApplicationHandle(appToken.asBinder());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800349 }
350
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800351 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
352 firstWindowDrawn = true;
353
354 // We now have a good window to show, remove dead placeholders
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700355 removeDeadWindows();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800356
Jorim Jaggi02886a82016-12-06 09:10:06 -0800357 if (startingWindow != null) {
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800358 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
359 + win.mToken + ": first real window is shown, no animation");
360 // If this initial window is animating, stop it -- we will do an animation to reveal
361 // it from behind the starting window, so there is no need for it to also be doing its
362 // own stuff.
Jorim Jaggia5e10572017-11-15 14:36:26 +0100363 win.cancelAnimation();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800364 removeStartingWindow();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800365 }
366 updateReportedVisibilityLocked();
367 }
368
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800369 void updateReportedVisibilityLocked() {
370 if (appToken == null) {
371 return;
372 }
373
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700374 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700375 final int count = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800376
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700377 mReportedVisibilityResults.reset();
378
379 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700380 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700381 win.updateReportedVisibility(mReportedVisibilityResults);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800382 }
383
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700384 int numInteresting = mReportedVisibilityResults.numInteresting;
385 int numVisible = mReportedVisibilityResults.numVisible;
386 int numDrawn = mReportedVisibilityResults.numDrawn;
387 boolean nowGone = mReportedVisibilityResults.nowGone;
388
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700389 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200390 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting && !isHidden();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700391 if (!nowGone) {
392 // If the app is not yet gone, then it can only become visible/drawn.
393 if (!nowDrawn) {
394 nowDrawn = reportedDrawn;
395 }
396 if (!nowVisible) {
397 nowVisible = reportedVisible;
398 }
399 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800400 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800401 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700402 if (nowDrawn != reportedDrawn) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800403 if (mActivityRecord != null) {
404 mActivityRecord.onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700405 }
406 reportedDrawn = nowDrawn;
407 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800408 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700409 if (DEBUG_VISIBILITY) Slog.v(TAG,
410 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800411 reportedVisible = nowVisible;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800412 if (mActivityRecord != null) {
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800413 if (nowVisible) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800414 onWindowsVisible();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800415 } else {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800416 onWindowsGone();
Wale Ogunwale26c0dfe2016-12-14 14:42:30 -0800417 }
418 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800419 }
420 }
421
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800422 private void onWindowsGone() {
423 if (mActivityRecord == null) {
424 return;
425 }
426 if (DEBUG_VISIBILITY) {
427 Slog.v(TAG_WM, "Reporting gone in " + mActivityRecord.appToken);
428 }
429 mActivityRecord.onWindowsGone();
430 }
431
432 private void onWindowsVisible() {
433 if (mActivityRecord == null) {
434 return;
435 }
436 if (DEBUG_VISIBILITY) {
437 Slog.v(TAG_WM, "Reporting visible in " + mActivityRecord.appToken);
438 }
439 mActivityRecord.onWindowsVisible();
440 }
441
Wale Ogunwale89973222017-04-23 18:39:45 -0700442 boolean isClientHidden() {
443 return mClientHidden;
444 }
445
446 void setClientHidden(boolean hideClient) {
447 if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
448 return;
449 }
Jorim Jaggi067b5bf2018-02-23 17:42:39 +0100450 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
451 + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
Wale Ogunwale89973222017-04-23 18:39:45 -0700452 mClientHidden = hideClient;
453 sendAppVisibilityToClients();
454 }
455
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800456 void setVisibility(boolean visible, boolean deferHidingClient) {
457 final AppTransition appTransition = getDisplayContent().mAppTransition;
458
459 // Don't set visibility to false if we were already not visible. This prevents WM from
460 // adding the app to the closing app list which doesn't make sense for something that is
461 // already not visible. However, set visibility to true even if we are already visible.
462 // This makes sure the app is added to the opening apps list so that the right
463 // transition can be selected.
464 // TODO: Probably a good idea to separate the concept of opening/closing apps from the
465 // concept of setting visibility...
466 if (!visible && hiddenRequested) {
467
468 if (!deferHidingClient && mDeferHidingClient) {
469 // We previously deferred telling the client to hide itself when visibility was
470 // initially set to false. Now we would like it to hide, so go ahead and set it.
471 mDeferHidingClient = deferHidingClient;
472 setClientHidden(true);
473 }
474 return;
475 }
476
477 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
478 Slog.v(TAG_WM, "setAppVisibility("
479 + appToken + ", visible=" + visible + "): " + appTransition
480 + " hidden=" + isHidden() + " hiddenRequested="
481 + hiddenRequested + " Callers=" + Debug.getCallers(6));
482 }
483
484 final DisplayContent displayContent = getDisplayContent();
485 displayContent.mOpeningApps.remove(this);
486 displayContent.mClosingApps.remove(this);
487 waitingToShow = false;
488 hiddenRequested = !visible;
489 mDeferHidingClient = deferHidingClient;
490
491 if (!visible) {
492 // If the app is dead while it was visible, we kept its dead window on screen.
493 // Now that the app is going invisible, we can remove it. It will be restarted
494 // if made visible again.
495 removeDeadWindows();
496 } else {
497 if (!appTransition.isTransitionSet()
498 && appTransition.isReady()) {
499 // Add the app mOpeningApps if transition is unset but ready. This means
500 // we're doing a screen freeze, and the unfreeze will wait for all opening
501 // apps to be ready.
502 displayContent.mOpeningApps.add(this);
503 }
504 startingMoved = false;
505 // If the token is currently hidden (should be the common case), or has been
506 // stopped, then we need to set up to wait for its windows to be ready.
507 if (isHidden() || mAppStopped) {
508 clearAllDrawn();
509
510 // If the app was already visible, don't reset the waitingToShow state.
511 if (isHidden()) {
512 waitingToShow = true;
513 }
514 }
515
516 // In the case where we are making an app visible but holding off for a transition,
517 // we still need to tell the client to make its windows visible so they get drawn.
518 // Otherwise, we will wait on performing the transition until all windows have been
519 // drawn, they never will be, and we are sad.
520 setClientHidden(false);
521
522 requestUpdateWallpaperIfNeeded();
523
524 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + this);
525 mAppStopped = false;
526
527 transferStartingWindowFromHiddenAboveTokenIfNeeded();
528 }
529
530 // If we are preparing an app transition, then delay changing
531 // the visibility of this token until we execute that transition.
532 if (okToAnimate() && appTransition.isTransitionSet()) {
533 inPendingTransaction = true;
534 if (visible) {
535 displayContent.mOpeningApps.add(this);
536 mEnteringAnimation = true;
537 } else {
538 displayContent.mClosingApps.add(this);
539 mEnteringAnimation = false;
540 }
541 if (appTransition.getAppTransition()
542 == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
543 // We're launchingBehind, add the launching activity to mOpeningApps.
544 final WindowState win = getDisplayContent().findFocusedWindow();
545 if (win != null) {
546 final AppWindowToken focusedToken = win.mAppToken;
547 if (focusedToken != null) {
548 if (DEBUG_APP_TRANSITIONS) {
549 Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
550 + " adding " + focusedToken + " to mOpeningApps");
551 }
552 // Force animation to be loaded.
553 focusedToken.setHidden(true);
554 displayContent.mOpeningApps.add(focusedToken);
555 }
556 }
557 }
558 return;
559 }
560
561 commitVisibility(null, visible, TRANSIT_UNSET, true, mVoiceInteraction);
562 updateReportedVisibilityLocked();
563 }
564
565 boolean commitVisibility(WindowManager.LayoutParams lp,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700566 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
567
568 boolean delayed = false;
569 inPendingTransaction = false;
Wale Ogunwale9e4721f2017-05-23 19:37:30 -0700570 // Reset the state of mHiddenSetFromTransferredStartingWindow since visibility is actually
571 // been set by the app now.
572 mHiddenSetFromTransferredStartingWindow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700573
574 // Allow for state changes and animation to be applied if:
575 // * token is transitioning visibility state
576 // * or the token was marked as hidden and is exiting before we had a chance to play the
577 // transition animation
578 // * or this is an opening app and windows are being replaced.
579 boolean visibilityChanged = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200580 if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800581 final AccessibilityController accessibilityController =
582 mWmService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700583 boolean changed = false;
584 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200585 "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700586
587 boolean runningAppAnimation = false;
588
Jorim Jaggif84e2f62018-01-16 14:17:59 +0100589 if (transit != WindowManager.TRANSIT_UNSET) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200590 if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700591 delayed = runningAppAnimation = true;
592 }
593 final WindowState window = findMainWindow();
594 //TODO (multidisplay): Magnification is supported only for the default display.
595 if (window != null && accessibilityController != null
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700596 && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700597 accessibilityController.onAppWindowTransitionLocked(window, transit);
598 }
599 changed = true;
600 }
601
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700602 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700603 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700604 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700605 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700606 }
607
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200608 setHidden(!visible);
609 hiddenRequested = !visible;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700610 visibilityChanged = true;
611 if (!visible) {
612 stopFreezingScreen(true, true);
613 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700614 // If we are being set visible, and the starting window is not yet displayed,
615 // then make sure it doesn't get displayed.
616 if (startingWindow != null && !startingWindow.isDrawnLw()) {
617 startingWindow.mPolicyVisibility = false;
618 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700619 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -0700620
621 // We are becoming visible, so better freeze the screen with the windows that are
622 // getting visible so we also wait for them.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800623 forAllWindows(mWmService::makeWindowFreezingScreenIfNeededLocked, true);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700624 }
625
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800626 if (DEBUG_APP_TRANSITIONS) {
627 Slog.v(TAG_WM, "commitVisibility: " + this
628 + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
629 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700630
631 if (changed) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800632 getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700633 if (performLayout) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800634 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700635 false /*updateInputWindows*/);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800636 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700637 }
Arthur Hung95b38a92018-07-20 18:56:12 +0800638 getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700639 }
640 }
641
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200642 if (isReallyAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700643 delayed = true;
Jorim Jaggiab9fcb22018-03-15 23:46:12 +0100644 } else {
645
646 // We aren't animating anything, but exiting windows rely on the animation finished
647 // callback being called in case the AppWindowToken was pretending to be animating,
648 // which we might have done because we were in closing/opening apps list.
649 onAnimationFinished();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700650 }
651
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700652 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100653 if ((mChildren.get(i)).isSelfOrChildAnimating()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700654 delayed = true;
655 }
656 }
657
658 if (visibilityChanged) {
659 if (visible && !delayed) {
660 // The token was made immediately visible, there will be no entrance animation.
661 // We need to inform the client the enter animation was finished.
662 mEnteringAnimation = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800663 mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(
664 token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700665 }
Robert Carr61b81112017-07-17 18:08:15 -0700666
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800667 // If we're becoming visible, immediately change client visibility as well. there seem
668 // to be some edge cases where we change our visibility but client visibility never gets
669 // updated.
Jorim Jaggi110839b2018-01-22 12:49:04 +0100670 // If we're becoming invisible, update the client visibility if we are not running an
671 // animation. Otherwise, we'll update client visibility in onAnimationFinished.
Jorim Jaggi3cad57f2018-02-20 18:32:01 +0100672 if (visible || !isReallyAnimating()) {
Jorim Jaggi110839b2018-01-22 12:49:04 +0100673 setClientHidden(!visible);
Jorim Jaggi4876b4a2018-01-11 15:43:49 +0100674 }
675
lumark588a3e82018-07-20 18:53:54 +0800676 if (!getDisplayContent().mClosingApps.contains(this)
677 && !getDisplayContent().mOpeningApps.contains(this)) {
chaviwa953fcf2018-03-01 12:00:39 -0800678 // The token is not closing nor opening, so even if there is an animation set, that
679 // doesn't mean that it goes through the normal app transition cycle so we have
680 // to inform the docked controller about visibility change.
681 // TODO(multi-display): notify docked divider on all displays where visibility was
682 // affected.
lumark588a3e82018-07-20 18:53:54 +0800683 getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged();
chaviwa953fcf2018-03-01 12:00:39 -0800684
685 // Take the screenshot before possibly hiding the WSA, otherwise the screenshot
686 // will not be taken.
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800687 mWmService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
chaviwa953fcf2018-03-01 12:00:39 -0800688 }
689
Robert Carre7cc44d2017-03-20 19:04:30 -0700690 // If we are hidden but there is no delay needed we immediately
691 // apply the Surface transaction so that the ActivityManager
Robert Carr61b81112017-07-17 18:08:15 -0700692 // can have some guarantee on the Surface state following
693 // setting the visibility. This captures cases like dismissing
694 // the docked or pinned stack where there is no app transition.
695 //
696 // In the case of a "Null" animation, there will be
697 // no animation but there will still be a transition set.
698 // We still need to delay hiding the surface such that it
699 // can be synchronized with showing the next surface in the transition.
lumark588a3e82018-07-20 18:53:54 +0800700 if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) {
Robert Carr6914f082017-03-20 19:04:30 -0700701 SurfaceControl.openTransaction();
702 for (int i = mChildren.size() - 1; i >= 0; i--) {
703 mChildren.get(i).mWinAnimator.hide("immediately hidden");
704 }
705 SurfaceControl.closeTransaction();
706 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700707 }
708
709 return delayed;
710 }
711
Jorim Jaggi87fdbcb2017-08-17 13:41:11 +0200712 /**
713 * @return The to top most child window for which {@link LayoutParams#isFullscreen()} returns
714 * true.
715 */
716 WindowState getTopFullscreenWindow() {
717 for (int i = mChildren.size() - 1; i >= 0; i--) {
718 final WindowState win = mChildren.get(i);
719 if (win != null && win.mAttrs.isFullscreen()) {
720 return win;
721 }
722 }
723 return null;
724 }
725
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800726 WindowState findMainWindow() {
Matthew Ng53e66b22018-01-12 17:13:13 -0800727 return findMainWindow(true);
728 }
729
730 /**
731 * Finds the main window that either has type base application or application starting if
732 * requested.
733 *
734 * @param includeStartingApp Allow to search application-starting windows to also be returned.
735 * @return The main window of type base application or application starting if requested.
736 */
737 WindowState findMainWindow(boolean includeStartingApp) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700738 WindowState candidate = null;
Matthew Ng53e66b22018-01-12 17:13:13 -0800739 for (int j = mChildren.size() - 1; j >= 0; --j) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700740 final WindowState win = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700741 final int type = win.mAttrs.type;
742 // No need to loop through child window as base application and starting types can't be
743 // child windows.
Matthew Ng53e66b22018-01-12 17:13:13 -0800744 if (type == TYPE_BASE_APPLICATION
745 || (includeStartingApp && type == TYPE_APPLICATION_STARTING)) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700746 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900747 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700748 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800749 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700750 candidate = win;
751 } else {
752 return win;
753 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800754 }
755 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700756 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800757 }
758
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800759 boolean windowsAreFocusable() {
Tiger Huang51c5a1d2018-12-11 20:24:51 +0800760 if (mTargetSdk < Build.VERSION_CODES.Q) {
761 final int pid = mActivityRecord != null
762 ? (mActivityRecord.app != null ? mActivityRecord.app.getPid() : 0) : 0;
763 final AppWindowToken topFocusedAppOfMyProcess =
764 mWmService.mRoot.mTopFocusedAppByProcess.get(pid);
765 if (topFocusedAppOfMyProcess != null && topFocusedAppOfMyProcess != this) {
766 // For the apps below Q, there can be only one app which has the focused window per
767 // process, because legacy apps may not be ready for a multi-focus system.
768 return false;
769 }
770 }
Wale Ogunwale3382ab12017-07-27 08:55:03 -0700771 return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800772 }
773
Wale Ogunwale571771c2016-08-26 13:18:50 -0700774 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700775 boolean isVisible() {
Wale Ogunwalee471be62016-10-03 07:53:55 -0700776 // If the app token isn't hidden then it is considered visible and there is no need to check
777 // its children windows to see if they are visible.
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200778 return !isHidden();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700779 }
780
781 @Override
Wale Ogunwalee287e192017-04-21 09:30:12 -0700782 void removeImmediately() {
783 onRemovedFromDisplay();
Yunfan Chen3a77f282018-12-12 15:47:52 -0800784 if (mActivityRecord != null) {
785 mActivityRecord.unregisterConfigurationChangeListener(this);
786 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700787 super.removeImmediately();
788 }
789
790 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700791 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800792 mIsExiting = false;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800793 removeAllWindowsIfPossible();
Bryce Lee6d410262017-02-28 15:30:17 -0800794 removeImmediately();
Craig Mautnere3119b72015-01-20 15:02:36 -0800795 }
796
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700797 @Override
798 boolean checkCompleteDeferredRemoval() {
799 if (mIsExiting) {
800 removeIfPossible();
801 }
802 return super.checkCompleteDeferredRemoval();
803 }
804
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700805 void onRemovedFromDisplay() {
Wale Ogunwalee287e192017-04-21 09:30:12 -0700806 if (mRemovingFromDisplay) {
807 return;
808 }
809 mRemovingFromDisplay = true;
810
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700811 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
812
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800813 boolean delayed = commitVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700814
lumark588a3e82018-07-20 18:53:54 +0800815 getDisplayContent().mOpeningApps.remove(this);
816 getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800817 mWmService.mTaskSnapshotController.onAppRemoved(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700818 waitingToShow = false;
lumark588a3e82018-07-20 18:53:54 +0800819 if (getDisplayContent().mClosingApps.contains(this)) {
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700820 delayed = true;
lumark588a3e82018-07-20 18:53:54 +0800821 } else if (getDisplayContent().mAppTransition.isTransitionSet()) {
822 getDisplayContent().mClosingApps.add(this);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700823 delayed = true;
824 }
825
826 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200827 + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700828
829 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
830 + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
831
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800832 if (startingData != null) {
833 removeStartingWindow();
Jorim Jaggi19be6052017-08-03 18:33:43 +0200834 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800835
Winson Chung87e5d552017-04-05 11:49:38 -0700836 // If this window was animating, then we need to ensure that the app transition notifies
lumark588a3e82018-07-20 18:53:54 +0800837 // that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
838 // so add to that list now
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200839 if (isSelfAnimating()) {
lumark588a3e82018-07-20 18:53:54 +0800840 getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
Winson Chung87e5d552017-04-05 11:49:38 -0700841 }
842
Wale Ogunwalee287e192017-04-21 09:30:12 -0700843 final TaskStack stack = getStack();
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700844 if (delayed && !isEmpty()) {
845 // set the token aside because it has an active animation to be finished
846 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
847 "removeAppToken make exiting: " + this);
Wale Ogunwalee287e192017-04-21 09:30:12 -0700848 if (stack != null) {
849 stack.mExitingAppTokens.add(this);
850 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700851 mIsExiting = true;
852 } else {
853 // Make sure there is no animation running on this token, so any windows associated
854 // with it will be removed as soon as their animations are complete
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200855 cancelAnimation();
Wale Ogunwale3106ae012017-05-16 08:56:37 -0700856 if (stack != null) {
857 stack.mExitingAppTokens.remove(this);
858 }
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700859 removeIfPossible();
860 }
861
862 removed = true;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700863 stopFreezingScreen(true, true);
Bryce Lee6d410262017-02-28 15:30:17 -0800864
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800865 final DisplayContent dc = getDisplayContent();
866 if (dc.mFocusedApp == this) {
867 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
868 + " displayId=" + dc.getDisplayId());
869 dc.setFocusedApp(null);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800870 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700871 }
872
873 if (!delayed) {
874 updateReportedVisibilityLocked();
875 }
Wale Ogunwalee287e192017-04-21 09:30:12 -0700876
877 mRemovingFromDisplay = false;
Wale Ogunwaleac2561e2016-11-01 15:43:46 -0700878 }
879
Chong Zhange05bcb12016-07-26 17:47:29 -0700880 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700881 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700882 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700883 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700884 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700885 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700886 if (wallpaperMightChange) {
887 requestUpdateWallpaperIfNeeded();
888 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700889 }
890
Robert Carre12aece2016-02-02 22:43:27 -0800891 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700892 destroySurfaces(false /*cleanupOnResume*/);
893 }
894
895 /**
896 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
897 * the client has finished with them.
898 *
899 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
900 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
901 * others so that they are ready to be reused. If set to false (common case), destroy all
902 * surfaces that's eligible, if the app is already stopped.
903 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700904 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700905 boolean destroyedSomething = false;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100906
907 // Copying to a different list as multiple children can be removed.
Jorim Jaggi59f3e922018-01-05 15:40:32 +0100908 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
Jorim Jaggia5e10572017-11-15 14:36:26 +0100909 for (int i = children.size() - 1; i >= 0; i--) {
910 final WindowState win = children.get(i);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700911 destroyedSomething |= win.destroySurface(cleanupOnResume, mAppStopped);
Robert Carre12aece2016-02-02 22:43:27 -0800912 }
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700913 if (destroyedSomething) {
914 final DisplayContent dc = getDisplayContent();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700915 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Adrian Roos23df3a32018-03-15 15:41:13 +0100916 updateLetterboxSurface(null);
Robert Carre12aece2016-02-02 22:43:27 -0800917 }
918 }
919
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800920 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700921 * Notify that the app is now resumed, and it was not stopped before, perform a clean
922 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800923 */
Jorim Jaggibae01b12017-04-11 16:29:10 -0700924 void notifyAppResumed(boolean wasStopped) {
Chong Zhangad24f962016-08-25 12:12:33 -0700925 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
Jorim Jaggibae01b12017-04-11 16:29:10 -0700926 + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700927 mAppStopped = false;
chaviwd3bf08d2017-08-01 17:24:59 -0700928 // Allow the window to turn the screen on once the app is resumed again.
929 setCanTurnScreenOn(true);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700930 if (!wasStopped) {
931 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800932 }
Robert Carre12aece2016-02-02 22:43:27 -0800933 }
934
Chong Zhangbef461f2015-10-27 11:38:24 -0700935 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700936 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
937 * keeping alive in case they were still being used.
938 */
939 void notifyAppStopped() {
940 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
941 mAppStopped = true;
942 destroySurfaces();
943 // Remove any starting window that was added for this app if they are still around.
Yunfan Chen1ee84ea2018-11-13 16:03:37 -0800944 removeStartingWindow();
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700945 }
946
Chong Zhang92147042016-05-09 12:47:11 -0700947 void clearAllDrawn() {
948 allDrawn = false;
949 deferClearAllDrawn = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700950 }
951
Bryce Lee6d410262017-02-28 15:30:17 -0800952 Task getTask() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800953 return (Task) getParent();
Bryce Lee6d410262017-02-28 15:30:17 -0800954 }
955
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800956 TaskStack getStack() {
957 final Task task = getTask();
958 if (task != null) {
959 return task.mStack;
960 } else {
961 return null;
962 }
963 }
964
Bryce Lee6d410262017-02-28 15:30:17 -0800965 @Override
966 void onParentSet() {
967 super.onParentSet();
968
Robert Carred3e83b2017-04-21 13:26:55 -0700969 final Task task = getTask();
970
Bryce Lee6d410262017-02-28 15:30:17 -0800971 // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
972 // access visual elements like the {@link DisplayContent}. We must remove any associations
973 // such as animations.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800974 if (!mReparenting) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800975 if (task == null) {
976 // It is possible we have been marked as a closing app earlier. We must remove ourselves
977 // from this list so we do not participate in any future animations.
lumark588a3e82018-07-20 18:53:54 +0800978 getDisplayContent().mClosingApps.remove(this);
Robert Carred3e83b2017-04-21 13:26:55 -0700979 } else if (mLastParent != null && mLastParent.mStack != null) {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -0800980 task.mStack.mExitingAppTokens.remove(this);
981 }
Bryce Lee6d410262017-02-28 15:30:17 -0800982 }
Jorim Jaggi6de61012018-03-19 14:53:23 +0100983 final TaskStack stack = getStack();
984
985 // If we reparent, make sure to remove ourselves from the old animation registry.
986 if (mAnimatingAppWindowTokenRegistry != null) {
987 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
988 }
989 mAnimatingAppWindowTokenRegistry = stack != null
990 ? stack.getAnimatingAppWindowTokenRegistry()
991 : null;
992
Robert Carred3e83b2017-04-21 13:26:55 -0700993 mLastParent = task;
chaviwdcf76ec2019-01-11 16:48:46 -0800994
995 updateColorTransform();
Bryce Lee6d410262017-02-28 15:30:17 -0800996 }
997
Wale Ogunwalefa854eb2016-09-20 13:43:52 -0700998 void postWindowRemoveStartingWindowCleanup(WindowState win) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700999 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001000 if (startingWindow == win) {
1001 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001002 removeStartingWindow();
Wale Ogunwale6c459212017-05-17 08:56:03 -07001003 } else if (mChildren.size() == 0) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001004 // If this is the last window and we had requested a starting transition window,
1005 // well there is no point now.
Jorim Jaggi02886a82016-12-06 09:10:06 -08001006 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001007 startingData = null;
Wale Ogunwale6c459212017-05-17 08:56:03 -07001008 if (mHiddenSetFromTransferredStartingWindow) {
1009 // We set the hidden state to false for the token from a transferred starting window.
1010 // We now reset it back to true since the starting window was the last window in the
1011 // token.
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001012 setHidden(true);
Wale Ogunwale6c459212017-05-17 08:56:03 -07001013 }
Jorim Jaggi829b9cd2017-01-23 16:20:53 +01001014 } else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001015 // If this is the last window except for a starting transition window,
1016 // we need to get rid of the starting transition.
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001017 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
1018 + win);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001019 removeStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001020 }
1021 }
1022
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001023 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001024 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001025 WindowState win = mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -08001026 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001027 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001028 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -08001029 // Set mDestroying, we don't want any animation or delayed removal here.
1030 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001031 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001032 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -08001033 }
1034 }
1035 }
1036
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001037 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001038 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001039 // No need to loop through child windows as the answer should be the same as that of the
1040 // parent window.
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001041 if (!(mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07001042 return true;
1043 }
1044 }
1045 return false;
1046 }
1047
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001048 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001049 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1050 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -08001051
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001052 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001053 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001054 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -08001055 }
Robert Carra1eb4392015-12-10 12:43:51 -08001056 }
1057
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001058 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001059 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -08001060 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001061 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001062 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001063 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -08001064 }
1065 }
1066
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001067 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001068 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1069 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -08001070
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001071 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001072 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001073 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -08001074 }
1075 }
1076
Chong Zhang4d7369a2016-04-25 16:09:14 -07001077 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001078 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001079 final WindowState w = mChildren.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -07001080 w.requestUpdateWallpaperIfNeeded();
1081 }
1082 }
1083
Chong Zhangd78ddb42016-03-02 17:01:14 -08001084 boolean isRelaunching() {
1085 return mPendingRelaunchCount > 0;
1086 }
1087
Robert Carr68375192017-06-13 12:41:53 -07001088 boolean shouldFreezeBounds() {
1089 final Task task = getTask();
1090
1091 // For freeform windows, we can't freeze the bounds at the moment because this would make
1092 // the resizing unresponsive.
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001093 if (task == null || task.inFreeformWindowingMode()) {
Robert Carr68375192017-06-13 12:41:53 -07001094 return false;
1095 }
1096
1097 // We freeze the bounds while drag resizing to deal with the time between
1098 // the divider/drag handle being released, and the handling it's new
1099 // configuration. If we are relaunched outside of the drag resizing state,
1100 // we need to be careful not to do this.
1101 return getTask().isDragResizing();
1102 }
1103
Chong Zhangd78ddb42016-03-02 17:01:14 -08001104 void startRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001105 if (shouldFreezeBounds()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001106 freezeBounds();
1107 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001108
1109 // In the process of tearing down before relaunching, the app will
1110 // try and clean up it's child surfaces. We need to prevent this from
1111 // happening, so we sever the children, transfering their ownership
1112 // from the client it-self to the parent surface (owned by us).
Robert Carr29daa922018-04-27 11:56:48 -07001113 detachChildren();
1114
1115 mPendingRelaunchCount++;
1116 }
1117
1118 void detachChildren() {
Robert Carrfd8e93b2018-05-10 13:40:25 -07001119 SurfaceControl.openTransaction();
Robert Carrd5c7dd62017-03-08 10:39:30 -08001120 for (int i = mChildren.size() - 1; i >= 0; i--) {
1121 final WindowState w = mChildren.get(i);
1122 w.mWinAnimator.detachChildren();
1123 }
Robert Carrfd8e93b2018-05-10 13:40:25 -07001124 SurfaceControl.closeTransaction();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001125 }
1126
1127 void finishRelaunching() {
Robert Carr68375192017-06-13 12:41:53 -07001128 unfreezeBounds();
1129
Chong Zhangd78ddb42016-03-02 17:01:14 -08001130 if (mPendingRelaunchCount > 0) {
1131 mPendingRelaunchCount--;
Bryce Lee081554b2017-05-25 07:52:12 -07001132 } else {
1133 // Update keyguard flags upon finishing relaunch.
1134 checkKeyguardFlagsChanged();
Chong Zhangd78ddb42016-03-02 17:01:14 -08001135 }
1136 }
1137
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001138 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001139 if (mPendingRelaunchCount == 0) {
1140 return;
1141 }
Robert Carr68375192017-06-13 12:41:53 -07001142 unfreezeBounds();
Wale Ogunwale8fd75422016-06-24 14:20:37 -07001143 mPendingRelaunchCount = 0;
1144 }
1145
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001146 /**
1147 * Returns true if the new child window we are adding to this token is considered greater than
1148 * the existing child window in this token in terms of z-order.
1149 */
1150 @Override
1151 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
1152 WindowState existingWindow) {
1153 final int type1 = newWindow.mAttrs.type;
1154 final int type2 = existingWindow.mAttrs.type;
1155
1156 // Base application windows should be z-ordered BELOW all other windows in the app token.
1157 if (type1 == TYPE_BASE_APPLICATION && type2 != TYPE_BASE_APPLICATION) {
1158 return false;
1159 } else if (type1 != TYPE_BASE_APPLICATION && type2 == TYPE_BASE_APPLICATION) {
1160 return true;
1161 }
1162
1163 // Starting windows should be z-ordered ABOVE all other windows in the app token.
1164 if (type1 == TYPE_APPLICATION_STARTING && type2 != TYPE_APPLICATION_STARTING) {
1165 return true;
1166 } else if (type1 != TYPE_APPLICATION_STARTING && type2 == TYPE_APPLICATION_STARTING) {
1167 return false;
1168 }
1169
1170 // Otherwise the new window is greater than the existing window.
1171 return true;
1172 }
1173
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001174 @Override
Robert Carra1eb4392015-12-10 12:43:51 -08001175 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001176 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001177
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001178 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001179 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001180 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001181 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
1182 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001183
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001184 // if we got a replacement window, reset the timeout to give drawing more time
1185 if (gotReplacementWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001186 mWmService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -08001187 }
Jorim Jaggife762342016-10-13 14:33:27 +02001188 checkKeyguardFlagsChanged();
1189 }
1190
1191 @Override
1192 void removeChild(WindowState child) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001193 if (!mChildren.contains(child)) {
1194 // This can be true when testing.
1195 return;
1196 }
Jorim Jaggife762342016-10-13 14:33:27 +02001197 super.removeChild(child);
1198 checkKeyguardFlagsChanged();
Adrian Roos23df3a32018-03-15 15:41:13 +01001199 updateLetterboxSurface(child);
Robert Carra1eb4392015-12-10 12:43:51 -08001200 }
1201
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001202 private boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001203 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001204 final WindowState candidate = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001205 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -08001206 return true;
1207 }
1208 }
1209 return false;
1210 }
1211
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001212 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001213 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001214 (mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -08001215 }
1216 }
1217
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001218 void reparent(Task task, int position) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001219 if (DEBUG_ADD_REMOVE) {
1220 Slog.i(TAG_WM, "reparent: moving app token=" + this
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001221 + " to task=" + task.mTaskId + " at " + position);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001222 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001223 if (task == null) {
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001224 throw new IllegalArgumentException("reparent: could not find task");
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001225 }
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001226 final Task currentTask = getTask();
1227 if (task == currentTask) {
Winson Chung30480042017-01-26 10:55:34 -08001228 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001229 "window token=" + this + " already child of task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001230 }
Bryce Lee6d410262017-02-28 15:30:17 -08001231
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001232 if (currentTask.mStack != task.mStack) {
Bryce Lee6d410262017-02-28 15:30:17 -08001233 throw new IllegalArgumentException(
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001234 "window token=" + this + " current task=" + currentTask
Bryce Lee6d410262017-02-28 15:30:17 -08001235 + " belongs to a different stack than " + task);
1236 }
1237
Winson Chung30480042017-01-26 10:55:34 -08001238 if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001239 + " from task=" + currentTask);
Winson Chung30480042017-01-26 10:55:34 -08001240 final DisplayContent prevDisplayContent = getDisplayContent();
1241
Bryce Lee6d410262017-02-28 15:30:17 -08001242 mReparenting = true;
1243
Winson Chung30480042017-01-26 10:55:34 -08001244 getParent().removeChild(this);
1245 task.addChild(this, position);
1246
Bryce Lee6d410262017-02-28 15:30:17 -08001247 mReparenting = false;
1248
Winson Chung30480042017-01-26 10:55:34 -08001249 // Relayout display(s).
1250 final DisplayContent displayContent = task.getDisplayContent();
1251 displayContent.setLayoutNeeded();
1252 if (prevDisplayContent != displayContent) {
1253 onDisplayChanged(displayContent);
1254 prevDisplayContent.setLayoutNeeded();
1255 }
Yunfan Chen0e7aff92018-12-05 16:35:32 -08001256 getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
Winson Chung30480042017-01-26 10:55:34 -08001257 }
1258
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001259 @Override
1260 void onDisplayChanged(DisplayContent dc) {
1261 DisplayContent prevDc = mDisplayContent;
1262 super.onDisplayChanged(dc);
1263 if (prevDc != null && prevDc.mFocusedApp == this) {
1264 prevDc.setFocusedApp(null);
lumarkbf844642018-11-23 17:11:36 +08001265 final TaskStack stack = dc.getTopStack();
1266 if (stack != null) {
1267 final Task task = stack.getTopChild();
1268 if (task != null && task.getTopChild() == this) {
1269 dc.setFocusedApp(this);
1270 }
Tiger Huang1e5b10a2018-07-30 20:19:51 +08001271 }
1272 }
1273 }
1274
Jorim Jaggi0429f352015-12-22 16:29:16 +01001275 /**
1276 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
1277 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
1278 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
1279 * with a queue.
1280 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001281 private void freezeBounds() {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001282 final Task task = getTask();
1283 mFrozenBounds.offer(new Rect(task.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001284
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001285 if (task.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001286 // We didn't call prepareFreezingBounds on the task, so use the current value.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001287 mFrozenMergedConfig.offer(new Configuration(task.getConfiguration()));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001288 } else {
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001289 mFrozenMergedConfig.offer(new Configuration(task.mPreparedFrozenMergedConfig));
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001290 }
Andrii Kulianb10330d2016-09-16 13:51:46 -07001291 // Calling unset() to make it equal to Configuration.EMPTY.
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08001292 task.mPreparedFrozenMergedConfig.unset();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001293 }
1294
1295 /**
1296 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
1297 */
Chong Zhangd78ddb42016-03-02 17:01:14 -08001298 private void unfreezeBounds() {
Robert Carr68375192017-06-13 12:41:53 -07001299 if (mFrozenBounds.isEmpty()) {
1300 return;
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001301 }
Robert Carr68375192017-06-13 12:41:53 -07001302 mFrozenBounds.remove();
Wale Ogunwale37dbafc2016-06-27 10:15:20 -07001303 if (!mFrozenMergedConfig.isEmpty()) {
1304 mFrozenMergedConfig.remove();
1305 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001306 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001307 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001308 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +01001309 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001310 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +01001311 }
1312
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001313 void setAppLayoutChanges(int changes, String reason) {
1314 if (!mChildren.isEmpty()) {
1315 final DisplayContent dc = getDisplayContent();
1316 dc.pendingLayoutChanges |= changes;
1317 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001318 mWmService.mWindowPlacerLocked.debugLayoutRepeats(reason, dc.pendingLayoutChanges);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001319 }
1320 }
1321 }
1322
1323 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001324 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001325 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001326 if (win.removeReplacedWindowIfNeeded(replacement)) {
1327 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001328 }
1329 }
1330 }
1331
1332 void startFreezingScreen() {
1333 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001334 + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001335 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001336 if (!hiddenRequested) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001337 if (!mFreezingScreen) {
1338 mFreezingScreen = true;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001339 mWmService.registerAppFreezeListener(this);
1340 mWmService.mAppsFreezingScreen++;
1341 if (mWmService.mAppsFreezingScreen == 1) {
1342 mWmService.startFreezingDisplayLocked(0, 0, getDisplayContent());
1343 mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1344 mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001345 }
1346 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001347 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001348 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001349 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001350 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001351 }
1352 }
1353 }
1354
1355 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001356 if (!mFreezingScreen) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001357 return;
1358 }
1359 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001360 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001361 boolean unfrozeWindows = false;
1362 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -07001363 final WindowState w = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001364 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001365 }
1366 if (force || unfrozeWindows) {
1367 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001368 mFreezingScreen = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001369 mWmService.unregisterAppFreezeListener(this);
1370 mWmService.mAppsFreezingScreen--;
1371 mWmService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001372 }
1373 if (unfreezeSurfaceNow) {
1374 if (unfrozeWindows) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001375 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001376 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001377 mWmService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001378 }
1379 }
1380
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001381 @Override
1382 public void onAppFreezeTimeout() {
1383 Slog.w(TAG_WM, "Force clearing freeze: " + this);
1384 stopFreezingScreen(true, true);
1385 }
1386
Jorim Jaggi60f9c972018-02-01 19:21:07 +01001387 /**
1388 * Tries to transfer the starting window from a token that's above ourselves in the task but
1389 * not visible anymore. This is a common scenario apps use: Trampoline activity T start main
1390 * activity M in the same task. Now, when reopening the task, T starts on top of M but then
1391 * immediately finishes after, so we have to transfer T to M.
1392 */
1393 void transferStartingWindowFromHiddenAboveTokenIfNeeded() {
1394 final Task task = getTask();
1395 for (int i = task.mChildren.size() - 1; i >= 0; i--) {
1396 final AppWindowToken fromToken = task.mChildren.get(i);
1397 if (fromToken == this) {
1398 return;
1399 }
1400 if (fromToken.hiddenRequested && transferStartingWindow(fromToken.token)) {
1401 return;
1402 }
1403 }
1404 }
1405
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001406 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale02319a62016-09-26 15:21:22 -07001407 final AppWindowToken fromToken = getDisplayContent().getAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001408 if (fromToken == null) {
1409 return false;
1410 }
1411
1412 final WindowState tStartingWindow = fromToken.startingWindow;
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08001413 if (tStartingWindow != null && fromToken.startingSurface != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001414 // In this case, the starting icon has already been displayed, so start
1415 // letting windows get shown immediately without any more transitions.
lumark588a3e82018-07-20 18:53:54 +08001416 getDisplayContent().mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001417
1418 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1419 + " from " + fromToken + " to " + this);
1420
1421 final long origId = Binder.clearCallingIdentity();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001422 try {
1423 // Transfer the starting window over to the new token.
1424 startingData = fromToken.startingData;
1425 startingSurface = fromToken.startingSurface;
1426 startingDisplayed = fromToken.startingDisplayed;
1427 fromToken.startingDisplayed = false;
1428 startingWindow = tStartingWindow;
1429 reportedVisible = fromToken.reportedVisible;
1430 fromToken.startingData = null;
1431 fromToken.startingSurface = null;
1432 fromToken.startingWindow = null;
1433 fromToken.startingMoved = true;
1434 tStartingWindow.mToken = this;
1435 tStartingWindow.mAppToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001436
Peter Visontay3556a3b2017-11-01 17:23:17 +00001437 if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1438 "Removing starting " + tStartingWindow + " from " + fromToken);
1439 fromToken.removeChild(tStartingWindow);
1440 fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
1441 fromToken.mHiddenSetFromTransferredStartingWindow = false;
1442 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001443
Peter Visontay3556a3b2017-11-01 17:23:17 +00001444 // Propagate other interesting state between the tokens. If the old token is displayed,
1445 // we should immediately force the new one to be displayed. If it is animating, we need
1446 // to move that animation to the new one.
1447 if (fromToken.allDrawn) {
1448 allDrawn = true;
1449 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1450 }
1451 if (fromToken.firstWindowDrawn) {
1452 firstWindowDrawn = true;
1453 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001454 if (!fromToken.isHidden()) {
1455 setHidden(false);
Peter Visontay3556a3b2017-11-01 17:23:17 +00001456 hiddenRequested = false;
1457 mHiddenSetFromTransferredStartingWindow = true;
1458 }
1459 setClientHidden(fromToken.mClientHidden);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001460
Jorim Jaggi980c9de2017-11-17 01:41:37 +01001461 transferAnimation(fromToken);
1462
1463 // When transferring an animation, we no longer need to apply an animation to the
1464 // the token we transfer the animation over. Thus, remove the animation from
1465 // pending opening apps.
lumark588a3e82018-07-20 18:53:54 +08001466 getDisplayContent().mOpeningApps.remove(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001467
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001468 mWmService.updateFocusedWindowLocked(
Peter Visontay3556a3b2017-11-01 17:23:17 +00001469 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
1470 getDisplayContent().setLayoutNeeded();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001471 mWmService.mWindowPlacerLocked.performSurfacePlacement();
Peter Visontay3556a3b2017-11-01 17:23:17 +00001472 } finally {
1473 Binder.restoreCallingIdentity(origId);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001474 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001475 return true;
1476 } else if (fromToken.startingData != null) {
1477 // The previous app was getting ready to show a
1478 // starting window, but hasn't yet done so. Steal it!
1479 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1480 "Moving pending starting from " + fromToken + " to " + this);
1481 startingData = fromToken.startingData;
1482 fromToken.startingData = null;
1483 fromToken.startingMoved = true;
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001484 scheduleAddStartingWindow();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001485 return true;
1486 }
1487
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001488 // TODO: Transfer thumbnail
1489
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001490 return false;
1491 }
1492
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001493 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001494 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001495 }
1496
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001497 @Override
1498 void onAppTransitionDone() {
1499 sendingToBottom = false;
1500 }
1501
Wale Ogunwale51362492016-09-08 17:49:17 -07001502 /**
1503 * We override because this class doesn't want its children affecting its reported orientation
1504 * in anyway.
1505 */
1506 @Override
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001507 int getOrientation(int candidate) {
Wale Ogunwale5e5a68d2017-03-24 17:36:38 -07001508 if (candidate == SCREEN_ORIENTATION_BEHIND) {
1509 // Allow app to specify orientation regardless of its visibility state if the current
1510 // candidate want us to use orientation behind. I.e. the visible app on-top of this one
1511 // wants us to use the orientation of the app behind it.
1512 return mOrientation;
1513 }
1514
Bryce Lee61fbcbc2017-03-10 14:14:03 -08001515 // The {@link AppWindowToken} should only specify an orientation when it is not closing or
1516 // going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
1517 // an Activity in another task being started in the wrong orientation during the transition.
lumark588a3e82018-07-20 18:53:54 +08001518 if (!(sendingToBottom || getDisplayContent().mClosingApps.contains(this))
1519 && (isVisible() || getDisplayContent().mOpeningApps.contains(this))) {
Bryce Leea163b762017-01-24 11:05:01 -08001520 return mOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -07001521 }
Bryce Leea163b762017-01-24 11:05:01 -08001522
1523 return SCREEN_ORIENTATION_UNSET;
Wale Ogunwale51362492016-09-08 17:49:17 -07001524 }
1525
Wale Ogunwaleb198b742016-12-01 08:44:09 -08001526 /** Returns the app's preferred orientation regardless of its currently visibility state. */
1527 int getOrientationIgnoreVisibility() {
1528 return mOrientation;
1529 }
1530
Craig Mautnerdbb79912012-03-01 18:59:14 -08001531 @Override
Winson Chunge55c0192017-08-24 14:50:48 -07001532 public void onConfigurationChanged(Configuration newParentConfig) {
1533 final int prevWinMode = getWindowingMode();
1534 super.onConfigurationChanged(newParentConfig);
1535 final int winMode = getWindowingMode();
1536
1537 if (prevWinMode == winMode) {
1538 return;
1539 }
1540
1541 if (prevWinMode != WINDOWING_MODE_UNDEFINED && winMode == WINDOWING_MODE_PINNED) {
1542 // Entering PiP from fullscreen, reset the snap fraction
1543 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
Winson Chung82267ce2018-04-06 16:38:26 -07001544 } else if (prevWinMode == WINDOWING_MODE_PINNED && winMode != WINDOWING_MODE_UNDEFINED
1545 && !isHidden()) {
Winson Chunge55c0192017-08-24 14:50:48 -07001546 // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds
1547 // for the next re-entry into PiP (assuming the activity is not hidden or destroyed)
1548 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
1549 if (pinnedStack != null) {
Winson Chung8efa1652018-06-06 09:34:23 -07001550 final Rect stackBounds;
1551 if (pinnedStack.lastAnimatingBoundsWasToFullscreen()) {
1552 // We are animating the bounds, use the pre-animation bounds to save the snap
1553 // fraction
1554 stackBounds = pinnedStack.mPreAnimationBounds;
1555 } else {
1556 // We skip the animation if the fullscreen configuration is not compatible, so
1557 // use the current bounds to calculate the saved snap fraction instead
1558 // (see PinnedActivityStack.skipResizeAnimation())
1559 stackBounds = mTmpRect;
1560 pinnedStack.getBounds(stackBounds);
1561 }
Winson Chunge55c0192017-08-24 14:50:48 -07001562 mDisplayContent.mPinnedStackControllerLocked.saveReentrySnapFraction(this,
Winson Chung8efa1652018-06-06 09:34:23 -07001563 stackBounds);
Winson Chunge55c0192017-08-24 14:50:48 -07001564 }
1565 }
1566 }
1567
1568 @Override
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001569 void checkAppWindowsReadyToShow() {
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001570 if (allDrawn == mLastAllDrawn) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001571 return;
1572 }
1573
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001574 mLastAllDrawn = allDrawn;
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001575 if (!allDrawn) {
1576 return;
1577 }
1578
1579 // The token has now changed state to having all windows shown... what to do, what to do?
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001580 if (mFreezingScreen) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001581 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001582 stopFreezingScreen(false, true);
1583 if (DEBUG_ORIENTATION) Slog.i(TAG,
1584 "Setting mOrientationChangeComplete=true because wtoken " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001585 + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001586 // This will set mOrientationChangeComplete and cause a pass through layout.
1587 setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001588 "checkAppWindowsReadyToShow: freezingScreen");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001589 } else {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001590 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow");
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001591
1592 // We can now show all of the drawn windows!
lumark588a3e82018-07-20 18:53:54 +08001593 if (!getDisplayContent().mOpeningApps.contains(this) && canShowWindows()) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001594 showAllWindowsLocked();
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001595 }
1596 }
1597 }
1598
Matthew Ng5d23afa2017-06-21 16:16:24 -07001599 /**
Bryce Leed390deb2017-06-22 13:14:28 -07001600 * Returns whether the drawn window states of this {@link AppWindowToken} has considered every
1601 * child {@link WindowState}. A child is considered if it has been passed into
1602 * {@link #updateDrawnWindowStates(WindowState)} after being added. This is used to determine
1603 * whether states, such as {@code allDrawn}, can be set, which relies on state variables such as
1604 * {@code mNumInterestingWindows}, which depend on all {@link WindowState}s being considered.
1605 *
1606 * @return {@code true} If all children have been considered, {@code false}.
1607 */
1608 private boolean allDrawnStatesConsidered() {
Bryce Lee6311c4b2017-07-06 14:09:29 -07001609 for (int i = mChildren.size() - 1; i >= 0; --i) {
1610 final WindowState child = mChildren.get(i);
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001611 if (child.mightAffectAllDrawn() && !child.getDrawnStateEvaluated()) {
Bryce Leed390deb2017-06-22 13:14:28 -07001612 return false;
1613 }
1614 }
1615 return true;
1616 }
1617
1618 /**
Matthew Ng5d23afa2017-06-21 16:16:24 -07001619 * Determines if the token has finished drawing. This should only be called from
1620 * {@link DisplayContent#applySurfaceChangesTransaction}
1621 */
Matthew Ng498c71d2017-04-18 13:55:45 -07001622 void updateAllDrawn() {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001623 if (!allDrawn) {
Matthew Ng498c71d2017-04-18 13:55:45 -07001624 // Number of drawn windows can be less when a window is being relaunched, wait for
Bryce Leed390deb2017-06-22 13:14:28 -07001625 // all windows to be launched and drawn for this token be considered all drawn.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001626 final int numInteresting = mNumInterestingWindows;
Bryce Leed390deb2017-06-22 13:14:28 -07001627
1628 // We must make sure that all present children have been considered (determined by
1629 // {@link #allDrawnStatesConsidered}) before evaluating whether everything has been
1630 // drawn.
1631 if (numInteresting > 0 && allDrawnStatesConsidered()
1632 && mNumDrawnWindows >= numInteresting && !isRelaunching()) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001633 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001634 + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001635 allDrawn = true;
1636 // Force an additional layout pass where
1637 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
Matthew Ng498c71d2017-04-18 13:55:45 -07001638 if (mDisplayContent != null) {
1639 mDisplayContent.setLayoutNeeded();
1640 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001641 mWmService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Robert Carrecc06b32017-04-18 14:25:10 -07001642
Winson Chunge7ba6862017-05-24 12:13:33 -07001643 // Notify the pinned stack upon all windows drawn. If there was an animation in
1644 // progress then this signal will resume that animation.
Wale Ogunwale61911492017-10-11 08:50:50 -07001645 final TaskStack pinnedStack = mDisplayContent.getPinnedStack();
Winson Chunge7ba6862017-05-24 12:13:33 -07001646 if (pinnedStack != null) {
1647 pinnedStack.onAllWindowsDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -07001648 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001649 }
1650 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001651 }
1652
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001653 boolean keyDispatchingTimedOut(String reason, int windowPid) {
1654 return mActivityRecord != null && mActivityRecord.keyDispatchingTimedOut(reason, windowPid);
1655 }
1656
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001657 /**
1658 * Updated this app token tracking states for interesting and drawn windows based on the window.
1659 *
1660 * @return Returns true if the input window is considered interesting and drawn while all the
1661 * windows in this app token where not considered drawn as of the last pass.
1662 */
1663 boolean updateDrawnWindowStates(WindowState w) {
Bryce Leed390deb2017-06-22 13:14:28 -07001664 w.setDrawnStateEvaluated(true /*evaluated*/);
1665
Jorim Jaggie4b0f282017-05-17 15:10:29 +02001666 if (DEBUG_STARTING_WINDOW_VERBOSE && w == startingWindow) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001667 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001668 + " allDrawn=" + allDrawn + " freezingScreen=" + mFreezingScreen);
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001669 }
1670
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001671 if (allDrawn && !mFreezingScreen) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001672 return false;
1673 }
1674
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001675 if (mLastTransactionSequence != mWmService.mTransactionSequence) {
1676 mLastTransactionSequence = mWmService.mTransactionSequence;
Matthew Ng53e66b22018-01-12 17:13:13 -08001677 mNumDrawnWindows = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001678 startingDisplayed = false;
Matthew Ng53e66b22018-01-12 17:13:13 -08001679
1680 // There is the main base application window, even if it is exiting, wait for it
1681 mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001682 }
1683
1684 final WindowStateAnimator winAnimator = w.mWinAnimator;
1685
1686 boolean isInterestingAndDrawn = false;
1687
Jorim Jaggie7d2b852017-08-28 17:55:15 +02001688 if (!allDrawn && w.mightAffectAllDrawn()) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001689 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1690 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001691 + ", isAnimationSet=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001692 if (!w.isDrawnLw()) {
1693 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
1694 + " pv=" + w.mPolicyVisibility
1695 + " mDrawState=" + winAnimator.drawStateToString()
1696 + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
Jorim Jaggif5f9e122017-10-24 18:21:09 +02001697 + " a=" + isSelfAnimating());
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001698 }
1699 }
1700
1701 if (w != startingWindow) {
1702 if (w.isInteresting()) {
Matthew Ng53e66b22018-01-12 17:13:13 -08001703 // Add non-main window as interesting since the main app has already been added
1704 if (findMainWindow(false /* includeStartingApp */) != w) {
1705 mNumInterestingWindows++;
1706 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001707 if (w.isDrawnLw()) {
1708 mNumDrawnWindows++;
1709
1710 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
1711 + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
Jorim Jaggib0fc8172017-11-23 17:04:08 +00001712 + " freezingScreen=" + mFreezingScreen
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001713 + " mAppFreezing=" + w.mAppFreezing);
1714
1715 isInterestingAndDrawn = true;
1716 }
1717 }
1718 } else if (w.isDrawnLw()) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001719 if (mActivityRecord != null) {
1720 mActivityRecord.onStartingWindowDrawn(SystemClock.uptimeMillis());
Jorim Jaggi3878ca32017-02-02 17:13:05 -08001721 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001722 startingDisplayed = true;
1723 }
1724 }
1725
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001726 return isInterestingAndDrawn;
1727 }
1728
Adrian Roos23df3a32018-03-15 15:41:13 +01001729 void layoutLetterbox(WindowState winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001730 final WindowState w = findMainWindow();
Adrian Roosf93b6d22018-03-21 13:48:26 +01001731 if (w == null || winHint != null && w != winHint) {
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001732 return;
1733 }
Jorim Jaggia32da382018-03-28 18:01:22 +02001734 final boolean surfaceReady = w.isDrawnLw() // Regular case
Adrian Roosf93b6d22018-03-21 13:48:26 +01001735 || w.mWinAnimator.mSurfaceDestroyDeferred // The preserved surface is still ready.
1736 || w.isDragResizeChanged(); // Waiting for relayoutWindow to call preserveSurface.
1737 final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001738 if (needsLetterbox) {
1739 if (mLetterbox == null) {
1740 mLetterbox = new Letterbox(() -> makeChildSurface(null));
1741 }
Adrian Roos7af9d972018-11-30 15:26:27 +01001742 getPosition(mTmpPoint);
1743 mLetterbox.layout(getParent().getBounds(), w.getFrameLw(), mTmpPoint);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001744 } else if (mLetterbox != null) {
Adrian Roos23df3a32018-03-15 15:41:13 +01001745 mLetterbox.hide();
1746 }
1747 }
1748
1749 void updateLetterboxSurface(WindowState winHint) {
1750 final WindowState w = findMainWindow();
1751 if (w != winHint && winHint != null && w != null) {
1752 return;
1753 }
1754 layoutLetterbox(winHint);
1755 if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
1756 mLetterbox.applySurfaceChanges(mPendingTransaction);
Adrian Roos4d18a2e2017-12-19 19:08:05 +01001757 }
1758 }
1759
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001760 @Override
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001761 boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001762 // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent
1763 // before the non-exiting app tokens. So, we skip the exiting app tokens here.
1764 // TODO: Investigate if we need to continue to do this or if we can just process them
1765 // in-order.
1766 if (mIsExiting && !waitingForReplacement()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001767 return false;
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001768 }
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001769 return forAllWindowsUnchecked(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001770 }
1771
lumark588a3e82018-07-20 18:53:54 +08001772 @Override
1773 void forAllAppWindows(Consumer<AppWindowToken> callback) {
1774 callback.accept(this);
1775 }
1776
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -08001777 boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
1778 boolean traverseTopToBottom) {
1779 return super.forAllWindows(callback, traverseTopToBottom);
Wale Ogunwaleb783fd82016-11-04 09:51:54 -07001780 }
1781
1782 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001783 AppWindowToken asAppWindowToken() {
1784 // I am an app window token!
1785 return this;
1786 }
1787
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001788 boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
1789 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
1790 IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
1791 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
1792 // If the display is frozen, we won't do anything until the actual window is
1793 // displayed so there is no reason to put in the starting window.
1794 if (!okToDisplay()) {
1795 return false;
1796 }
1797
1798 if (startingData != null) {
1799 return false;
1800 }
1801
1802 final WindowState mainWin = findMainWindow();
1803 if (mainWin != null && mainWin.mWinAnimator.getShown()) {
1804 // App already has a visible window...why would you want a starting window?
1805 return false;
1806 }
1807
1808 final ActivityManager.TaskSnapshot snapshot =
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001809 mWmService.mTaskSnapshotController.getSnapshot(
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001810 getTask().mTaskId, getTask().mUserId,
1811 false /* restoreFromDisk */, false /* reducedResolution */);
1812 final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
1813 allowTaskSnapshot, activityCreated, fromRecents, snapshot);
1814
1815 if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
1816 return createSnapshot(snapshot);
1817 }
1818
1819 // If this is a translucent window, then don't show a starting window -- the current
1820 // effect (a full-screen opaque starting window that fades away to the real contents
1821 // when it is ready) does not work for this.
1822 if (DEBUG_STARTING_WINDOW) {
1823 Slog.v(TAG, "Checking theme of starting window: 0x" + Integer.toHexString(theme));
1824 }
1825 if (theme != 0) {
1826 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
1827 com.android.internal.R.styleable.Window,
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001828 mWmService.mCurrentUserId);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001829 if (ent == null) {
1830 // Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
1831 // see that.
1832 return false;
1833 }
1834 final boolean windowIsTranslucent = ent.array.getBoolean(
1835 com.android.internal.R.styleable.Window_windowIsTranslucent, false);
1836 final boolean windowIsFloating = ent.array.getBoolean(
1837 com.android.internal.R.styleable.Window_windowIsFloating, false);
1838 final boolean windowShowWallpaper = ent.array.getBoolean(
1839 com.android.internal.R.styleable.Window_windowShowWallpaper, false);
1840 final boolean windowDisableStarting = ent.array.getBoolean(
1841 com.android.internal.R.styleable.Window_windowDisablePreview, false);
1842 if (DEBUG_STARTING_WINDOW) {
1843 Slog.v(TAG, "Translucent=" + windowIsTranslucent
1844 + " Floating=" + windowIsFloating
1845 + " ShowWallpaper=" + windowShowWallpaper);
1846 }
1847 if (windowIsTranslucent) {
1848 return false;
1849 }
1850 if (windowIsFloating || windowDisableStarting) {
1851 return false;
1852 }
1853 if (windowShowWallpaper) {
1854 if (getDisplayContent().mWallpaperController
1855 .getWallpaperTarget() == null) {
1856 // If this theme is requesting a wallpaper, and the wallpaper
1857 // is not currently visible, then this effectively serves as
1858 // an opaque window and our starting window transition animation
1859 // can still work. We just need to make sure the starting window
1860 // is also showing the wallpaper.
1861 windowFlags |= FLAG_SHOW_WALLPAPER;
1862 } else {
1863 return false;
1864 }
1865 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001866 }
Yunfan Chen8a8c0ed2018-12-18 16:46:32 -08001867
1868 if (transferStartingWindow(transferFrom)) {
1869 return true;
1870 }
1871
1872 // There is no existing starting window, and we don't want to create a splash screen, so
1873 // that's it!
1874 if (type != STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
1875 return false;
1876 }
1877
1878 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
1879 startingData = new SplashScreenStartingData(mWmService, pkg,
1880 theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
1881 getMergedOverrideConfiguration());
1882 scheduleAddStartingWindow();
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001883 return true;
1884 }
1885
1886
1887 private boolean createSnapshot(ActivityManager.TaskSnapshot snapshot) {
1888 if (snapshot == null) {
1889 return false;
1890 }
1891
1892 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001893 startingData = new SnapshotStartingData(mWmService, snapshot);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001894 scheduleAddStartingWindow();
1895 return true;
1896 }
1897
1898 void scheduleAddStartingWindow() {
1899 // Note: we really want to do sendMessageAtFrontOfQueue() because we
1900 // want to process the message ASAP, before any other queued
1901 // messages.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001902 if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001903 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001904 mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001905 }
1906 }
1907
1908 private final Runnable mAddStartingWindow = new Runnable() {
1909
1910 @Override
1911 public void run() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001912 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001913 // There can only be one adding request, silly caller!
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001914 mWmService.mAnimationHandler.removeCallbacks(this);
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001915 }
1916
1917 if (startingData == null) {
1918 // Animation has been canceled... do nothing.
1919 if (DEBUG_STARTING_WINDOW) {
1920 Slog.v(TAG, "startingData was nulled out before handling"
1921 + " mAddStartingWindow: " + AppWindowToken.this);
1922 }
1923 return;
1924 }
1925
1926 if (DEBUG_STARTING_WINDOW) {
1927 Slog.v(TAG, "Add starting " + this + ": startingData=" + startingData);
1928 }
1929
1930 WindowManagerPolicy.StartingSurface surface = null;
1931 try {
1932 surface = startingData.createStartingSurface(AppWindowToken.this);
1933 } catch (Exception e) {
1934 Slog.w(TAG, "Exception when adding starting window", e);
1935 }
1936 if (surface != null) {
1937 boolean abort = false;
Wale Ogunwale8b19de92018-11-29 19:58:26 -08001938 synchronized (mWmService.mGlobalLock) {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001939 // If the window was successfully added, then
1940 // we need to remove it.
1941 if (removed || startingData == null) {
1942 if (DEBUG_STARTING_WINDOW) {
1943 Slog.v(TAG, "Aborted starting " + AppWindowToken.this
1944 + ": removed=" + removed + " startingData=" + startingData);
1945 }
1946 startingWindow = null;
1947 startingData = null;
1948 abort = true;
1949 } else {
1950 startingSurface = surface;
1951 }
1952 if (DEBUG_STARTING_WINDOW && !abort) {
1953 Slog.v(TAG, "Added starting " + AppWindowToken.this + ": startingWindow="
1954 + startingWindow + " startingView=" + startingSurface);
1955 }
1956 }
1957 if (abort) {
1958 surface.remove();
1959 }
1960 } else if (DEBUG_STARTING_WINDOW) {
1961 Slog.v(TAG, "Surface returned was null: " + AppWindowToken.this);
1962 }
1963 }
1964 };
1965
1966 private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
1967 boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
1968 ActivityManager.TaskSnapshot snapshot) {
1969 if (getDisplayContent().mAppTransition.getAppTransition()
1970 == TRANSIT_DOCK_TASK_FROM_RECENTS) {
1971 // TODO(b/34099271): Remove this statement to add back the starting window and figure
1972 // out why it causes flickering, the starting window appears over the thumbnail while
1973 // the docked from recents transition occurs
1974 return STARTING_WINDOW_TYPE_NONE;
1975 } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
1976 return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1977 } else if (taskSwitch && allowTaskSnapshot) {
Kevin58b47f12018-12-17 14:09:01 -08001978 if (mWmService.mLowRamTaskSnapshots) {
1979 // For low RAM devices, we use the splash screen starting window instead of the
1980 // task snapshot starting window.
1981 return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1982 }
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08001983 return snapshot == null ? STARTING_WINDOW_TYPE_NONE
1984 : snapshotOrientationSameAsTask(snapshot) || fromRecents
1985 ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
1986 } else {
1987 return STARTING_WINDOW_TYPE_NONE;
1988 }
1989 }
1990
1991
1992 private boolean snapshotOrientationSameAsTask(ActivityManager.TaskSnapshot snapshot) {
1993 if (snapshot == null) {
1994 return false;
1995 }
1996 return getTask().getConfiguration().orientation == snapshot.getOrientation();
1997 }
1998
1999 void removeStartingWindow() {
2000 if (startingWindow == null) {
2001 if (startingData != null) {
2002 // Starting window has not been added yet, but it is scheduled to be added.
2003 // Go ahead and cancel the request.
2004 if (DEBUG_STARTING_WINDOW) {
2005 Slog.v(TAG_WM, "Clearing startingData for token=" + this);
2006 }
2007 startingData = null;
2008 }
2009 return;
2010 }
2011
2012 final WindowManagerPolicy.StartingSurface surface;
2013 if (startingData != null) {
2014 surface = startingSurface;
2015 startingData = null;
2016 startingSurface = null;
2017 startingWindow = null;
2018 startingDisplayed = false;
2019 if (surface == null) {
2020 if (DEBUG_STARTING_WINDOW) {
2021 Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
2022 + "remove");
2023 }
2024 return;
2025 }
2026 } else {
2027 if (DEBUG_STARTING_WINDOW) {
2028 Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
2029 + this);
2030 }
2031 return;
2032 }
2033
2034 if (DEBUG_STARTING_WINDOW) {
2035 Slog.v(TAG_WM, "Schedule remove starting " + this
2036 + " startingWindow=" + startingWindow
2037 + " startingView=" + startingSurface
2038 + " Callers=" + Debug.getCallers(5));
2039 }
2040
2041 // Use the same thread to remove the window as we used to add it, as otherwise we end up
2042 // with things in the view hierarchy being called from different threads.
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002043 mWmService.mAnimationHandler.post(() -> {
Yunfan Chen1ee84ea2018-11-13 16:03:37 -08002044 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
2045 try {
2046 surface.remove();
2047 } catch (Exception e) {
2048 Slog.w(TAG_WM, "Exception when removing starting window", e);
2049 }
2050 });
2051 }
2052
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07002053 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07002054 boolean fillsParent() {
2055 return mFillsParent;
2056 }
2057
2058 void setFillsParent(boolean fillsParent) {
2059 mFillsParent = fillsParent;
2060 }
2061
Jorim Jaggife762342016-10-13 14:33:27 +02002062 boolean containsDismissKeyguardWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002063 // Window state is transient during relaunch. We are not guaranteed to be frozen during the
2064 // entirety of the relaunch.
2065 if (isRelaunching()) {
2066 return mLastContainsDismissKeyguardWindow;
2067 }
2068
Jorim Jaggife762342016-10-13 14:33:27 +02002069 for (int i = mChildren.size() - 1; i >= 0; i--) {
2070 if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
2071 return true;
2072 }
2073 }
2074 return false;
2075 }
2076
2077 boolean containsShowWhenLockedWindow() {
Bryce Lee081554b2017-05-25 07:52:12 -07002078 // When we are relaunching, it is possible for us to be unfrozen before our previous
2079 // windows have been added back. Using the cached value ensures that our previous
2080 // showWhenLocked preference is honored until relaunching is complete.
2081 if (isRelaunching()) {
2082 return mLastContainsShowWhenLockedWindow;
2083 }
2084
Jorim Jaggife762342016-10-13 14:33:27 +02002085 for (int i = mChildren.size() - 1; i >= 0; i--) {
2086 if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
2087 return true;
2088 }
2089 }
Bryce Lee081554b2017-05-25 07:52:12 -07002090
Jorim Jaggife762342016-10-13 14:33:27 +02002091 return false;
2092 }
2093
2094 void checkKeyguardFlagsChanged() {
2095 final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
2096 final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
2097 if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
2098 || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002099 mWmService.notifyKeyguardFlagsChanged(null /* callback */,
lumark588a3e82018-07-20 18:53:54 +08002100 getDisplayContent().getDisplayId());
Jorim Jaggife762342016-10-13 14:33:27 +02002101 }
2102 mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
2103 mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
2104 }
2105
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002106 WindowState getImeTargetBelowWindow(WindowState w) {
2107 final int index = mChildren.indexOf(w);
2108 if (index > 0) {
2109 final WindowState target = mChildren.get(index - 1);
2110 if (target.canBeImeTarget()) {
2111 return target;
2112 }
2113 }
2114 return null;
2115 }
2116
2117 WindowState getHighestAnimLayerWindow(WindowState currentTarget) {
2118 WindowState candidate = null;
2119 for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) {
2120 final WindowState w = mChildren.get(i);
2121 if (w.mRemoved) {
2122 continue;
2123 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02002124 if (candidate == null) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +00002125 candidate = w;
2126 }
2127 }
2128 return candidate;
2129 }
2130
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002131 /**
2132 * See {@link Activity#setDisablePreviewScreenshots}.
2133 */
2134 void setDisablePreviewScreenshots(boolean disable) {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002135 mDisablePreviewScreenshots = disable;
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002136 }
2137
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002138 /**
chaviwd3bf08d2017-08-01 17:24:59 -07002139 * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
2140 */
2141 void setCanTurnScreenOn(boolean canTurnScreenOn) {
2142 mCanTurnScreenOn = canTurnScreenOn;
2143 }
2144
2145 /**
2146 * Indicates whether the current launch can turn the screen on. This is to prevent multiple
2147 * relayouts from turning the screen back on. The screen should only turn on at most
2148 * once per activity resume.
2149 *
2150 * @return true if the screen can be turned on.
2151 */
2152 boolean canTurnScreenOn() {
2153 return mCanTurnScreenOn;
2154 }
2155
2156 /**
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002157 * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
2158 * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
2159 * we can't take a snapshot for other reasons, for example, if we have a secure window.
2160 *
2161 * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
2162 * screenshot.
2163 */
2164 boolean shouldUseAppThemeSnapshot() {
Wale Ogunwale6c459212017-05-17 08:56:03 -07002165 return mDisablePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
Jorim Jaggid635a4a2017-05-03 15:21:26 +02002166 true /* topToBottom */);
Jorim Jaggi0fe7ce962017-02-22 16:45:48 +01002167 }
2168
Jorim Jaggibe418292018-03-26 16:14:12 +02002169 SurfaceControl getAppAnimationLayer() {
Jorim Jaggi391790622018-04-18 15:30:44 +02002170 return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
2171 : needsZBoost() ? ANIMATION_LAYER_BOOSTED
2172 : ANIMATION_LAYER_STANDARD);
Jorim Jaggibe418292018-03-26 16:14:12 +02002173 }
2174
chaviw23ee71c2017-12-18 11:29:41 -08002175 @Override
Jorim Jaggi596a1992017-12-29 14:48:02 +01002176 public SurfaceControl getAnimationLeashParent() {
Robert Carrb9506032018-02-13 13:54:00 -08002177 // All normal app transitions take place in an animation layer which is below the pinned
2178 // stack but may be above the parent stacks of the given animating apps.
2179 // For transitions in the pinned stack (menu activity) we just let them occur as a child
2180 // of the pinned stack.
2181 if (!inPinnedWindowingMode()) {
2182 return getAppAnimationLayer();
2183 } else {
2184 return getStack().getSurfaceControl();
2185 }
chaviw23ee71c2017-12-18 11:29:41 -08002186 }
2187
Jorim Jaggic6976f02018-04-18 16:31:07 +02002188 private boolean shouldAnimate(int transit) {
2189 final boolean isSplitScreenPrimary =
2190 getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
2191 final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
2192
2193 // We animate always if it's not split screen primary, and only some special cases in split
2194 // screen primary because it causes issues with stack clipping when we run an un-minimize
2195 // animation at the same time.
2196 return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
2197 }
2198
Vishnu Naira2977262018-07-26 13:31:26 -07002199 /**
2200 * Creates a layer to apply crop to an animation.
2201 */
2202 private SurfaceControl createAnimationBoundsLayer(Transaction t) {
2203 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
2204 final SurfaceControl.Builder builder = makeAnimationLeash()
2205 .setParent(getAnimationLeashParent())
Vishnu Naire86bd982018-11-28 13:23:17 -08002206 .setName(getSurfaceControl() + " - animation-bounds");
Vishnu Naira2977262018-07-26 13:31:26 -07002207 final SurfaceControl boundsLayer = builder.build();
2208 t.show(boundsLayer);
2209 return boundsLayer;
2210 }
2211
Riddle Hsua118b3a2018-10-11 22:05:06 +08002212 /** Get position and crop region of animation. */
2213 @VisibleForTesting
2214 void getAnimationBounds(Point outPosition, Rect outBounds) {
2215 outPosition.set(0, 0);
2216 outBounds.setEmpty();
2217
2218 final TaskStack stack = getStack();
2219 final Task task = getTask();
2220 if (task != null && task.inFreeformWindowingMode()) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002221 task.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002222 } else if (stack != null) {
Evan Roskyed6767f2018-10-26 17:21:06 -07002223 stack.getRelativeDisplayedPosition(outPosition);
Riddle Hsua118b3a2018-10-11 22:05:06 +08002224 }
2225
2226 // Always use stack bounds in order to have the ability to animate outside the task region.
2227 // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
2228 // according to the bounds.
2229 if (stack != null) {
2230 stack.getBounds(outBounds);
2231 }
2232 // We have the relative position so the local position can be removed from bounds.
2233 outBounds.offsetTo(0, 0);
2234 }
2235
Evan Roskyed6767f2018-10-26 17:21:06 -07002236 @Override
2237 Rect getDisplayedBounds() {
2238 final Task task = getTask();
2239 if (task != null) {
2240 final Rect overrideDisplayedBounds = task.getOverrideDisplayedBounds();
2241 if (!overrideDisplayedBounds.isEmpty()) {
2242 return overrideDisplayedBounds;
2243 }
2244 }
2245 return getBounds();
2246 }
2247
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002248 boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
2249 boolean isVoiceInteraction) {
2250
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002251 if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002252 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Jorim Jaggic6976f02018-04-18 16:31:07 +02002253 Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
2254 + " atoken=" + this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002255 }
2256 cancelAnimation();
2257 return false;
2258 }
2259
2260 // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
2261 // to animate and it can cause strange artifacts when we unfreeze the display if some
2262 // different animation is running.
2263 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
2264 if (okToAnimate()) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002265 final AnimationAdapter adapter;
Riddle Hsua118b3a2018-10-11 22:05:06 +08002266 getAnimationBounds(mTmpPoint, mTmpRect);
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002267
2268 // Delaying animation start isn't compatible with remote animations at all.
lumark588a3e82018-07-20 18:53:54 +08002269 if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
Jorim Jaggic4d29f22018-03-22 16:30:56 +01002270 && !mSurfaceAnimator.isAnimationStartDelayed()) {
lumark588a3e82018-07-20 18:53:54 +08002271 adapter = getDisplayContent().mAppTransition.getRemoteAnimationController()
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002272 .createAnimationAdapter(this, mTmpPoint, mTmpRect);
2273 } else {
lumark588a3e82018-07-20 18:53:54 +08002274 final int appStackClipMode =
2275 getDisplayContent().mAppTransition.getAppStackClipMode();
Vishnu Naira2977262018-07-26 13:31:26 -07002276 mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
2277
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002278 final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
2279 if (a != null) {
2280 adapter = new LocalAnimationAdapter(
2281 new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
lumark588a3e82018-07-20 18:53:54 +08002282 getDisplayContent().mAppTransition.canSkipFirstFrame(),
Vishnu Naira2977262018-07-26 13:31:26 -07002283 appStackClipMode,
Jorim Jaggiaa763cd2018-03-22 23:20:36 +01002284 true /* isAppAnimation */),
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002285 mWmService.mSurfaceAnimationRunner);
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002286 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
2287 mNeedsZBoost = true;
2288 }
2289 mTransit = transit;
lumark588a3e82018-07-20 18:53:54 +08002290 mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002291 } else {
2292 adapter = null;
chaviw23ee71c2017-12-18 11:29:41 -08002293 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +01002294 }
2295 if (adapter != null) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002296 startAnimation(getPendingTransaction(), adapter, !isVisible());
Jorim Jaggi82c17862018-02-21 17:50:18 +01002297 if (adapter.getShowWallpaper()) {
2298 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2299 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002300 }
2301 } else {
2302 cancelAnimation();
2303 }
2304 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
2305
2306 return isReallyAnimating();
2307 }
2308
2309 private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
2310 boolean isVoiceInteraction) {
2311 final DisplayContent displayContent = getTask().getDisplayContent();
2312 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2313 final int width = displayInfo.appWidth;
2314 final int height = displayInfo.appHeight;
2315 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
2316 "applyAnimation: atoken=" + this);
2317
2318 // Determine the visible rect to calculate the thumbnail clip
2319 final WindowState win = findMainWindow();
2320 final Rect frame = new Rect(0, 0, width, height);
2321 final Rect displayFrame = new Rect(0, 0,
2322 displayInfo.logicalWidth, displayInfo.logicalHeight);
2323 final Rect insets = new Rect();
2324 final Rect stableInsets = new Rect();
2325 Rect surfaceInsets = null;
2326 final boolean freeform = win != null && win.inFreeformWindowingMode();
2327 if (win != null) {
2328 // Containing frame will usually cover the whole screen, including dialog windows.
2329 // For freeform workspace windows it will not cover the whole screen and it also
2330 // won't exactly match the final freeform window frame (e.g. when overlapping with
2331 // the status bar). In that case we need to use the final frame.
2332 if (freeform) {
chaviw492139a2018-07-16 16:07:35 -07002333 frame.set(win.getFrameLw());
Adrian Roos4d18a2e2017-12-19 19:08:05 +01002334 } else if (win.isLetterboxedAppWindow()) {
2335 frame.set(getTask().getBounds());
Winson Chungc1674272018-02-21 10:15:17 -08002336 } else if (win.isDockedResizing()) {
2337 // If we are animating while docked resizing, then use the stack bounds as the
2338 // animation target (which will be different than the task bounds)
2339 frame.set(getTask().getParent().getBounds());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002340 } else {
chaviw553b0212018-07-12 13:37:01 -07002341 frame.set(win.getContainingFrame());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002342 }
2343 surfaceInsets = win.getAttrs().surfaceInsets;
Adrian Roos20e07892018-02-23 19:12:01 +01002344 // XXX(b/72757033): These are insets relative to the window frame, but we're really
2345 // interested in the insets relative to the frame we chose in the if-blocks above.
chaviw9c81e632018-07-31 11:17:52 -07002346 win.getContentInsets(insets);
2347 win.getStableInsets(stableInsets);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002348 }
2349
2350 if (mLaunchTaskBehind) {
2351 // Differentiate the two animations. This one which is briefly on the screen
2352 // gets the !enter animation, and the other activity which remains on the
2353 // screen gets the enter animation. Both appear in the mOpeningApps set.
2354 enter = false;
2355 }
2356 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
2357 + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
2358 + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
2359 final Configuration displayConfig = displayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002360 final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002361 displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
2362 surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
2363 if (a != null) {
2364 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
2365 final int containingWidth = frame.width();
2366 final int containingHeight = frame.height();
2367 a.initialize(containingWidth, containingHeight, width, height);
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002368 a.scaleCurrentDuration(mWmService.getTransitionAnimationScaleLocked());
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002369 }
2370 return a;
2371 }
2372
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002373 @Override
Jorim Jaggi6de61012018-03-19 14:53:23 +01002374 public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
2375 return mAnimatingAppWindowTokenRegistry != null
2376 && mAnimatingAppWindowTokenRegistry.notifyAboutToFinish(
2377 this, endDeferFinishCallback);
2378 }
2379
2380 @Override
2381 public void onAnimationLeashDestroyed(Transaction t) {
2382 super.onAnimationLeashDestroyed(t);
Vishnu Naira2977262018-07-26 13:31:26 -07002383 if (mAnimationBoundsLayer != null) {
Robert Carr8810b692018-12-11 15:49:48 -08002384 t.reparent(mAnimationBoundsLayer, null);
Vishnu Naira2977262018-07-26 13:31:26 -07002385 mAnimationBoundsLayer = null;
2386 }
2387
Jorim Jaggi6de61012018-03-19 14:53:23 +01002388 if (mAnimatingAppWindowTokenRegistry != null) {
2389 mAnimatingAppWindowTokenRegistry.notifyFinished(this);
2390 }
2391 }
2392
2393 @Override
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002394 protected void setLayer(Transaction t, int layer) {
2395 if (!mSurfaceAnimator.hasLeash()) {
2396 t.setLayer(mSurfaceControl, layer);
2397 }
2398 }
2399
2400 @Override
2401 protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
2402 if (!mSurfaceAnimator.hasLeash()) {
2403 t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
2404 }
2405 }
2406
2407 @Override
2408 protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
2409 if (!mSurfaceAnimator.hasLeash()) {
2410 t.reparent(mSurfaceControl, newParent.getHandle());
2411 }
2412 }
2413
2414 @Override
2415 public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002416 // The leash is parented to the animation layer. We need to preserve the z-order by using
2417 // the prefix order index, but we boost if necessary.
Robert Carrb9506032018-02-13 13:54:00 -08002418 int layer = 0;
2419 if (!inPinnedWindowingMode()) {
2420 layer = getPrefixOrderIndex();
2421 } else {
2422 // Pinned stacks have animations take place within themselves rather than an animation
2423 // layer so we need to preserve the order relative to the stack (e.g. the order of our
2424 // task/parent).
2425 layer = getParent().getPrefixOrderIndex();
2426 }
2427
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002428 if (mNeedsZBoost) {
2429 layer += Z_BOOST_BASE;
2430 }
2431 leash.setLayer(layer);
Robert Carr2f8aa392018-01-31 14:46:51 -08002432
2433 final DisplayContent dc = getDisplayContent();
Jorim Jaggibe418292018-03-26 16:14:12 +02002434 dc.assignStackOrdering();
Jorim Jaggi6de61012018-03-19 14:53:23 +01002435 if (mAnimatingAppWindowTokenRegistry != null) {
2436 mAnimatingAppWindowTokenRegistry.notifyStarting(this);
2437 }
Vishnu Naira2977262018-07-26 13:31:26 -07002438
2439 // If the animation needs to be cropped then an animation bounds layer is created as a child
2440 // of the pinned stack or animation layer. The leash is then reparented to this new layer.
2441 if (mNeedsAnimationBoundsLayer) {
2442 final TaskStack stack = getStack();
2443 if (stack == null) {
2444 return;
2445 }
2446 mAnimationBoundsLayer = createAnimationBoundsLayer(t);
2447
2448 // Set clip rect to stack bounds.
2449 mTmpRect.setEmpty();
2450 stack.getBounds(mTmpRect);
2451
2452 // Crop to stack bounds.
2453 t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
2454
2455 // Reparent leash to animation bounds layer.
2456 t.reparent(leash, mAnimationBoundsLayer.getHandle());
2457 }
Jorim Jaggi619c9f72017-12-19 18:04:29 +01002458 }
2459
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002460 /**
2461 * This must be called while inside a transaction.
2462 */
2463 void showAllWindowsLocked() {
2464 forAllWindows(windowState -> {
2465 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + windowState);
2466 windowState.performShowLocked();
2467 }, false /* traverseTopToBottom */);
Jorim Jaggia5e10572017-11-15 14:36:26 +01002468 }
2469
2470 @Override
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002471 protected void onAnimationFinished() {
2472 super.onAnimationFinished();
2473
2474 mTransit = TRANSIT_UNSET;
2475 mTransitFlags = 0;
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002476 mNeedsZBoost = false;
Vishnu Naira2977262018-07-26 13:31:26 -07002477 mNeedsAnimationBoundsLayer = false;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002478
2479 setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
2480 "AppWindowToken");
2481
Jorim Jaggi988f6682017-11-17 17:46:43 +01002482 clearThumbnail();
Jorim Jaggi752cd822018-03-29 16:29:18 +02002483 setClientHidden(isHidden() && hiddenRequested);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002484
lumarkff0ab692018-11-05 20:32:30 +08002485 getDisplayContent().computeImeTargetIfNeeded(this);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002486
2487 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + this
2488 + ": reportedVisible=" + reportedVisible
2489 + " okToDisplay=" + okToDisplay()
2490 + " okToAnimate=" + okToAnimate()
2491 + " startingDisplayed=" + startingDisplayed);
2492
2493 // WindowState.onExitAnimationDone might modify the children list, so make a copy and then
2494 // traverse the copy.
2495 final ArrayList<WindowState> children = new ArrayList<>(mChildren);
2496 children.forEach(WindowState::onExitAnimationDone);
2497
lumark588a3e82018-07-20 18:53:54 +08002498 getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002499 scheduleAnimation();
2500 }
2501
2502 @Override
2503 boolean isAppAnimating() {
2504 return isSelfAnimating();
2505 }
2506
2507 @Override
2508 boolean isSelfAnimating() {
2509 // If we are about to start a transition, we also need to be considered animating.
2510 return isWaitingForTransitionStart() || isReallyAnimating();
2511 }
2512
2513 /**
2514 * @return True if and only if we are actually running an animation. Note that
2515 * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
2516 * start.
2517 */
2518 private boolean isReallyAnimating() {
2519 return super.isSelfAnimating();
2520 }
2521
Jorim Jaggi988f6682017-11-17 17:46:43 +01002522 @Override
2523 void cancelAnimation() {
2524 super.cancelAnimation();
2525 clearThumbnail();
2526 }
2527
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002528 boolean isWaitingForTransitionStart() {
lumark588a3e82018-07-20 18:53:54 +08002529 return getDisplayContent().mAppTransition.isTransitionSet()
2530 && (getDisplayContent().mOpeningApps.contains(this)
2531 || getDisplayContent().mClosingApps.contains(this));
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002532 }
2533
2534 public int getTransit() {
2535 return mTransit;
2536 }
2537
2538 int getTransitFlags() {
2539 return mTransitFlags;
2540 }
2541
Jorim Jaggi988f6682017-11-17 17:46:43 +01002542 void attachThumbnailAnimation() {
2543 if (!isReallyAnimating()) {
2544 return;
2545 }
2546 final int taskId = getTask().mTaskId;
2547 final GraphicBuffer thumbnailHeader =
lumark588a3e82018-07-20 18:53:54 +08002548 getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
Jorim Jaggi988f6682017-11-17 17:46:43 +01002549 if (thumbnailHeader == null) {
2550 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
2551 return;
2552 }
2553 clearThumbnail();
2554 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnailHeader);
2555 mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
2556 }
2557
Tony Mak64b8d562017-12-28 17:44:02 +00002558 /**
2559 * Attaches a surface with a thumbnail for the
2560 * {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
2561 */
2562 void attachCrossProfileAppsThumbnailAnimation() {
2563 if (!isReallyAnimating()) {
2564 return;
2565 }
2566 clearThumbnail();
2567
2568 final WindowState win = findMainWindow();
2569 if (win == null) {
2570 return;
2571 }
chaviw492139a2018-07-16 16:07:35 -07002572 final Rect frame = win.getFrameLw();
Wale Ogunwale8b19de92018-11-29 19:58:26 -08002573 final int thumbnailDrawableRes = getTask().mUserId == mWmService.mCurrentUserId
Tony Mak64b8d562017-12-28 17:44:02 +00002574 ? R.drawable.ic_account_circle
Tony Makda4af232018-04-27 11:01:10 +01002575 : R.drawable.ic_corp_badge;
Tony Mak64b8d562017-12-28 17:44:02 +00002576 final GraphicBuffer thumbnail =
lumark588a3e82018-07-20 18:53:54 +08002577 getDisplayContent().mAppTransition
Tony Mak64b8d562017-12-28 17:44:02 +00002578 .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
2579 if (thumbnail == null) {
2580 return;
2581 }
2582 mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
2583 final Animation animation =
lumark588a3e82018-07-20 18:53:54 +08002584 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
chaviw492139a2018-07-16 16:07:35 -07002585 win.getFrameLw());
Tony Mak64b8d562017-12-28 17:44:02 +00002586 mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
2587 frame.top));
2588 }
2589
Jorim Jaggi988f6682017-11-17 17:46:43 +01002590 private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
2591 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
2592
2593 // If this is a multi-window scenario, we use the windows frame as
2594 // destination of the thumbnail header animation. If this is a full screen
2595 // window scenario, we use the whole display as the target.
2596 WindowState win = findMainWindow();
2597 Rect appRect = win != null ? win.getContentFrameLw() :
2598 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
chaviw9c81e632018-07-31 11:17:52 -07002599 final Rect insets = win != null ? win.getContentInsets() : null;
Jorim Jaggi988f6682017-11-17 17:46:43 +01002600 final Configuration displayConfig = mDisplayContent.getConfiguration();
lumark588a3e82018-07-20 18:53:54 +08002601 return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
Jorim Jaggi988f6682017-11-17 17:46:43 +01002602 appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
2603 displayConfig.orientation);
2604 }
2605
2606 private void clearThumbnail() {
2607 if (mThumbnail == null) {
2608 return;
2609 }
2610 mThumbnail.destroy();
2611 mThumbnail = null;
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002612 }
2613
Jorim Jaggif84e2f62018-01-16 14:17:59 +01002614 void registerRemoteAnimations(RemoteAnimationDefinition definition) {
2615 mRemoteAnimationDefinition = definition;
2616 }
2617
2618 RemoteAnimationDefinition getRemoteAnimationDefinition() {
2619 return mRemoteAnimationDefinition;
2620 }
2621
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002622 @Override
2623 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
2624 super.dump(pw, prefix, dumpAll);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002625 if (appToken != null) {
Wale Ogunwale72919d22016-12-08 18:58:50 -08002626 pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002627 }
Winson Chung48b25652018-10-22 14:04:30 -07002628 pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
Bryce Lee7fbeb8a2017-03-02 08:42:30 -08002629 pw.print(prefix); pw.print("task="); pw.println(getTask());
Wale Ogunwale51362492016-09-08 17:49:17 -07002630 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
2631 pw.print(" mOrientation="); pw.println(mOrientation);
Wale Ogunwale89973222017-04-23 18:39:45 -07002632 pw.println(prefix + "hiddenRequested=" + hiddenRequested + " mClientHidden=" + mClientHidden
2633 + ((mDeferHidingClient) ? " mDeferHidingClient=" + mDeferHidingClient : "")
2634 + " reportedDrawn=" + reportedDrawn + " reportedVisible=" + reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07002635 if (paused) {
2636 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002637 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08002638 if (mAppStopped) {
2639 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
2640 }
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002641 if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002642 || allDrawn || mLastAllDrawn) {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07002643 pw.print(prefix); pw.print("mNumInterestingWindows=");
2644 pw.print(mNumInterestingWindows);
2645 pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002646 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07002647 pw.print(" allDrawn="); pw.print(allDrawn);
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002648 pw.print(" lastAllDrawn="); pw.print(mLastAllDrawn);
Craig Mautner6fbda632012-07-03 09:26:39 -07002649 pw.println(")");
2650 }
2651 if (inPendingTransaction) {
2652 pw.print(prefix); pw.print("inPendingTransaction=");
2653 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002654 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08002655 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002656 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
2657 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08002658 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08002659 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002660 }
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002661 if (startingWindow != null || startingSurface != null
Wale Ogunwale6c459212017-05-17 08:56:03 -07002662 || startingDisplayed || startingMoved || mHiddenSetFromTransferredStartingWindow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002663 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
Jorim Jaggiba41f4b2016-12-14 17:43:07 -08002664 pw.print(" startingSurface="); pw.print(startingSurface);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002665 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale6c459212017-05-17 08:56:03 -07002666 pw.print(" startingMoved="); pw.print(startingMoved);
2667 pw.println(" mHiddenSetFromTransferredStartingWindow="
2668 + mHiddenSetFromTransferredStartingWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002669 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01002670 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08002671 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002672 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08002673 }
2674 if (mPendingRelaunchCount != 0) {
2675 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01002676 }
Wale Ogunwalee287e192017-04-21 09:30:12 -07002677 if (mRemovingFromDisplay) {
2678 pw.println(prefix + "mRemovingFromDisplay=" + mRemovingFromDisplay);
2679 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002680 }
2681
2682 @Override
2683 void setHidden(boolean hidden) {
2684 super.setHidden(hidden);
Winson Chunge55c0192017-08-24 14:50:48 -07002685
2686 if (hidden) {
2687 // Once the app window is hidden, reset the last saved PiP snap fraction
2688 mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
2689 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002690 scheduleAnimation();
2691 }
2692
2693 @Override
2694 void prepareSurfaces() {
2695 // isSelfAnimating also returns true when we are about to start a transition, so we need
2696 // to check super here.
2697 final boolean reallyAnimating = super.isSelfAnimating();
2698 final boolean show = !isHidden() || reallyAnimating;
2699 if (show && !mLastSurfaceShowing) {
2700 mPendingTransaction.show(mSurfaceControl);
2701 } else if (!show && mLastSurfaceShowing) {
2702 mPendingTransaction.hide(mSurfaceControl);
Jorim Jaggi4d1835d2017-08-31 17:28:27 +02002703 }
Jorim Jaggi988f6682017-11-17 17:46:43 +01002704 if (mThumbnail != null) {
2705 mThumbnail.setShowing(mPendingTransaction, show);
2706 }
Jorim Jaggif5f9e122017-10-24 18:21:09 +02002707 mLastSurfaceShowing = show;
2708 super.prepareSurfaces();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002709 }
2710
Jorim Jaggi77d0f36c2018-03-16 17:49:49 +01002711 /**
2712 * @return Whether our {@link #getSurfaceControl} is currently showing.
2713 */
2714 boolean isSurfaceShowing() {
2715 return mLastSurfaceShowing;
2716 }
2717
Jorim Jaggib0fc8172017-11-23 17:04:08 +00002718 boolean isFreezingScreen() {
2719 return mFreezingScreen;
2720 }
2721
2722 @Override
2723 boolean needsZBoost() {
2724 return mNeedsZBoost || super.needsZBoost();
2725 }
2726
Wale Ogunwale0d5609b2017-09-13 05:55:07 -07002727 @CallSuper
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002728 @Override
Adrian Roos4921ccf2017-09-28 16:54:06 +02002729 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07002730 final long token = proto.start(fieldId);
2731 writeNameToProto(proto, NAME);
Adrian Roos4921ccf2017-09-28 16:54:06 +02002732 super.writeToProto(proto, WINDOW_TOKEN, trim);
Vishnu Nair04ab4392018-01-10 11:00:06 -08002733 proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
2734 proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
2735 proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
2736 if (mThumbnail != null){
2737 mThumbnail.writeToProto(proto, THUMBNAIL);
2738 }
2739 proto.write(FILLS_PARENT, mFillsParent);
2740 proto.write(APP_STOPPED, mAppStopped);
2741 proto.write(HIDDEN_REQUESTED, hiddenRequested);
2742 proto.write(CLIENT_HIDDEN, mClientHidden);
2743 proto.write(DEFER_HIDING_CLIENT, mDeferHidingClient);
2744 proto.write(REPORTED_DRAWN, reportedDrawn);
2745 proto.write(REPORTED_VISIBLE, reportedVisible);
2746 proto.write(NUM_INTERESTING_WINDOWS, mNumInterestingWindows);
2747 proto.write(NUM_DRAWN_WINDOWS, mNumDrawnWindows);
2748 proto.write(ALL_DRAWN, allDrawn);
2749 proto.write(LAST_ALL_DRAWN, mLastAllDrawn);
2750 proto.write(REMOVED, removed);
2751 if (startingWindow != null){
2752 startingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
2753 }
2754 proto.write(STARTING_DISPLAYED, startingDisplayed);
2755 proto.write(STARTING_MOVED, startingMoved);
2756 proto.write(HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW,
2757 mHiddenSetFromTransferredStartingWindow);
2758 for (Rect bounds : mFrozenBounds) {
2759 bounds.writeToProto(proto, FROZEN_BOUNDS);
2760 }
Steven Timotiusaf03df62017-07-18 16:56:43 -07002761 proto.end(token);
2762 }
2763
2764 void writeNameToProto(ProtoOutputStream proto, long fieldId) {
2765 if (appToken == null) {
2766 return;
2767 }
2768 try {
2769 proto.write(fieldId, appToken.getName());
2770 } catch (RemoteException e) {
2771 // This shouldn't happen, but in this case fall back to outputting nothing
2772 Slog.e(TAG, e.toString());
2773 }
2774 }
2775
2776 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002777 public String toString() {
2778 if (stringName == null) {
2779 StringBuilder sb = new StringBuilder();
2780 sb.append("AppWindowToken{");
2781 sb.append(Integer.toHexString(System.identityHashCode(this)));
2782 sb.append(" token="); sb.append(token); sb.append('}');
2783 stringName = sb.toString();
2784 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07002785 return stringName + ((mIsExiting) ? " mIsExiting=" : "");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002786 }
Adrian Roos20e07892018-02-23 19:12:01 +01002787
2788 Rect getLetterboxInsets() {
2789 if (mLetterbox != null) {
2790 return mLetterbox.getInsets();
2791 } else {
2792 return new Rect();
2793 }
2794 }
Adrian Roos23df3a32018-03-15 15:41:13 +01002795
2796 /**
2797 * @eturn true if there is a letterbox and any part of that letterbox overlaps with
2798 * the given {@code rect}.
2799 */
2800 boolean isLetterboxOverlappingWith(Rect rect) {
2801 return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
2802 }
chaviw4ad54912018-05-30 11:05:44 -07002803
2804 /**
2805 * Sets if this AWT is in the process of closing or entering PIP.
2806 * {@link #mWillCloseOrEnterPip}}
2807 */
2808 void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
2809 mWillCloseOrEnterPip = willCloseOrEnterPip;
2810 }
2811
2812 /**
2813 * Returns whether this AWT is considered closing. Conditions are either
2814 * 1. Is this app animating and was requested to be hidden
2815 * 2. App is delayed closing since it might enter PIP.
2816 */
2817 boolean isClosingOrEnteringPip() {
2818 return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
2819 }
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +02002820
2821 /**
2822 * @return Whether we are allowed to show non-starting windows at the moment. We disallow
2823 * showing windows during transitions in case we have windows that have wide-color-gamut
2824 * color mode set to avoid jank in the middle of the transition.
2825 */
2826 boolean canShowWindows() {
2827 return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
2828 }
2829
2830 /**
2831 * @return true if we have a window that has a non-default color mode set; false otherwise.
2832 */
2833 private boolean hasNonDefaultColorWindow() {
2834 return forAllWindows(ws -> ws.mAttrs.getColorMode() != COLOR_MODE_DEFAULT,
2835 true /* topToBottom */);
2836 }
lumark588a3e82018-07-20 18:53:54 +08002837
2838 void removeFromPendingTransition() {
2839 if (isWaitingForTransitionStart() && mDisplayContent != null) {
2840 mDisplayContent.mOpeningApps.remove(this);
2841 mDisplayContent.mClosingApps.remove(this);
2842 }
2843 }
chaviwdcf76ec2019-01-11 16:48:46 -08002844
2845 private void updateColorTransform() {
2846 if (mSurfaceControl != null && mLastAppSaturationInfo != null) {
2847 mPendingTransaction.setColorTransform(mSurfaceControl, mLastAppSaturationInfo.mMatrix,
2848 mLastAppSaturationInfo.mTranslation);
2849 mWmService.scheduleAnimationLocked();
2850 }
2851 }
2852
2853 private static class AppSaturationInfo {
2854 float[] mMatrix = new float[9];
2855 float[] mTranslation = new float[3];
2856
2857 void setSaturation(@Size(9) float[] matrix, @Size(3) float[] translation) {
2858 System.arraycopy(matrix, 0, mMatrix, 0, mMatrix.length);
2859 System.arraycopy(translation, 0, mTranslation, 0, mTranslation.length);
2860 }
2861 }
Jeff Browne9bdb312012-04-05 15:30:10 -07002862}