blob: e176c44f5bab08a21d4dcfe914f3c545501f1ba2 [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
Wale Ogunwale6cae7652015-12-26 07:36:26 -080019import static android.app.ActivityManager.StackId;
Wale Ogunwale51362492016-09-08 17:49:17 -070020import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070021import static android.view.Display.DEFAULT_DISPLAY;
Wale Ogunwaled1c37912016-08-16 03:19:39 -070022import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080023import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070024import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080025import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
Robert Carra1eb4392015-12-10 12:43:51 -080027import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070028import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
Wale Ogunwale9017ec02016-02-25 08:55:25 -080030import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080031import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
33import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
34import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang92147042016-05-09 12:47:11 -070035import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
Jorim Jaggi6626f542016-08-22 13:08:44 -070036import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070037import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070038import static com.android.server.wm.WindowManagerService.logWithStack;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080039
Jeff Brown4532e612012-04-05 14:27:12 -070040import com.android.server.input.InputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080041import com.android.server.wm.WindowManagerService.H;
42
Filip Gruszczynskia590c992015-11-25 16:45:26 -080043import android.annotation.NonNull;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070044import android.content.res.Configuration;
Jorim Jaggi0429f352015-12-22 16:29:16 +010045import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070046import android.os.Binder;
47import android.os.IBinder;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080048import android.os.Message;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070049import android.os.SystemClock;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080050import android.util.Slog;
51import android.view.IApplicationToken;
52import android.view.View;
53import android.view.WindowManager;
Jorim Jaggi6626f542016-08-22 13:08:44 -070054import android.view.animation.Animation;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080055
56import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +010057import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080058import java.util.ArrayList;
59
60class AppTokenList extends ArrayList<AppWindowToken> {
61}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080062
63/**
64 * Version of WindowToken that is specifically for a particular application (or
65 * really activity) that is displaying windows.
66 */
Craig Mautnere32c3072012-03-12 15:25:35 -070067class AppWindowToken extends WindowToken {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080068 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
69
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080070 // Non-null only for application tokens.
71 final IApplicationToken appToken;
72
Filip Gruszczynskia590c992015-11-25 16:45:26 -080073 @NonNull final AppWindowAnimator mAppAnimator;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070074
Dianne Hackborne30e02f2014-05-27 18:24:45 -070075 final boolean voiceInteraction;
76
Craig Mautner83162a92015-01-26 14:43:30 -080077 Task mTask;
Wale Ogunwale51362492016-09-08 17:49:17 -070078 /** @see WindowContainer#fillsParent() */
79 private boolean mFillsParent;
Craig Mautner4c5eb222013-11-18 12:59:05 -080080 boolean layoutConfigChanges;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -070081 boolean showForAllUsers;
Yorke Lee0e852472016-06-15 10:03:18 -070082 int targetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -070083
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080084 // The input dispatching timeout for this application token in nanoseconds.
85 long inputDispatchingTimeoutNanos;
86
87 // These are used for determining when all windows associated with
88 // an activity have been drawn, so they can be made visible together
89 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -070090 // initialize so that it doesn't match mTransactionSequence which is an int.
91 long lastTransactionSequence = Long.MIN_VALUE;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080092 int numInterestingWindows;
93 int numDrawnWindows;
94 boolean inPendingTransaction;
95 boolean allDrawn;
Craig Mautner7636dfb2012-11-16 15:24:11 -080096 // Set to true when this app creates a surface while in the middle of an animation. In that
97 // case do not clear allDrawn until the animation completes.
98 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080099
Chong Zhang8e4bda92016-05-04 15:08:18 -0700100 // These are to track the app's real drawing status if there were no saved surfaces.
101 boolean allDrawnExcludingSaved;
102 int numInterestingWindowsExcludingSaved;
Wale Ogunwale571771c2016-08-26 13:18:50 -0700103 int numDrawnWindowsExcludingSaved;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700104
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800105 // Is this window's surface needed? This is almost like hidden, except
106 // it will sometimes be true a little earlier: when the token has
107 // been shown, but is still waiting for its app transition to execute
108 // before making its windows shown.
109 boolean hiddenRequested;
110
111 // Have we told the window clients to hide themselves?
112 boolean clientHidden;
113
114 // Last visibility state we reported to the app token.
115 boolean reportedVisible;
116
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700117 // Last drawn state we reported to the app token.
118 boolean reportedDrawn;
119
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800120 // Set to true when the token has been removed from the window mgr.
121 boolean removed;
122
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800123 // Information about an application starting window if displayed.
124 StartingData startingData;
125 WindowState startingWindow;
126 View startingView;
127 boolean startingDisplayed;
128 boolean startingMoved;
129 boolean firstWindowDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700130 private final WindowState.UpdateReportedVisibilityResults mReportedVisibilityResults =
131 new WindowState.UpdateReportedVisibilityResults();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800132
133 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700134 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800135
Wale Ogunwale571771c2016-08-26 13:18:50 -0700136 // TODO: Have a WindowContainer state for tracking exiting/deferred removal.
Craig Mautner799bc1d2015-01-14 10:33:48 -0800137 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800138
Craig Mautnerbb742462014-07-07 15:28:55 -0700139 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700140 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700141
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800142 boolean mAlwaysFocusable;
143
Robert Carre12aece2016-02-02 22:43:27 -0800144 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700145 int mRotationAnimationHint;
Chong Zhangd78ddb42016-03-02 17:01:14 -0800146 int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800147
Robert Carr91b228092016-06-28 17:32:37 -0700148 private ArrayList<WindowSurfaceController.SurfaceControlWithBackground> mSurfaceViewBackgrounds =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700149 new ArrayList<>();
Robert Carr91b228092016-06-28 17:32:37 -0700150
Jorim Jaggi0429f352015-12-22 16:29:16 +0100151 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700152 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100153
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700154 AppWindowToken(WindowManagerService service, IApplicationToken token, boolean _voiceInteraction) {
155 super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true);
156 appToken = token;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700157 voiceInteraction = _voiceInteraction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800158 mInputApplicationHandle = new InputApplicationHandle(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700159 mAppAnimator = new AppWindowAnimator(this, service);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800160 }
161
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800162 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
163 firstWindowDrawn = true;
164
165 // We now have a good window to show, remove dead placeholders
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700166 removeDeadWindows();
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800167
168 if (startingData != null) {
169 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
170 + win.mToken + ": first real window is shown, no animation");
171 // If this initial window is animating, stop it -- we will do an animation to reveal
172 // it from behind the starting window, so there is no need for it to also be doing its
173 // own stuff.
174 winAnimator.clearAnimation();
175 winAnimator.mService.mFinishedStarting.add(this);
176 winAnimator.mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
177 }
178 updateReportedVisibilityLocked();
179 }
180
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800181 void updateReportedVisibilityLocked() {
182 if (appToken == null) {
183 return;
184 }
185
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700186 if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700187 final int count = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800188
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700189 mReportedVisibilityResults.reset();
190
191 for (int i = 0; i < count; i++) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700192 final WindowState win = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700193 win.updateReportedVisibility(mReportedVisibilityResults);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800194 }
195
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700196 int numInteresting = mReportedVisibilityResults.numInteresting;
197 int numVisible = mReportedVisibilityResults.numVisible;
198 int numDrawn = mReportedVisibilityResults.numDrawn;
199 boolean nowGone = mReportedVisibilityResults.nowGone;
200
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700201 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800202 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700203 if (!nowGone) {
204 // If the app is not yet gone, then it can only become visible/drawn.
205 if (!nowDrawn) {
206 nowDrawn = reportedDrawn;
207 }
208 if (!nowVisible) {
209 nowVisible = reportedVisible;
210 }
211 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800212 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800213 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700214 if (nowDrawn != reportedDrawn) {
215 if (nowDrawn) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700216 mService.mH.obtainMessage(H.REPORT_APPLICATION_TOKEN_DRAWN, this).sendToTarget();
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700217 }
218 reportedDrawn = nowDrawn;
219 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800220 if (nowVisible != reportedVisible) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700221 if (DEBUG_VISIBILITY) Slog.v(TAG,
222 "Visibility changed in " + this + ": vis=" + nowVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800223 reportedVisible = nowVisible;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700224 mService.mH.obtainMessage(H.REPORT_APPLICATION_TOKEN_WINDOWS,
225 nowVisible ? 1 : 0, nowGone ? 1 : 0, this).sendToTarget();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800226 }
227 }
228
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700229 boolean setVisibility(WindowManager.LayoutParams lp,
230 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
231
232 boolean delayed = false;
233 inPendingTransaction = false;
234
235 if (clientHidden == visible) {
236 clientHidden = !visible;
237 sendAppVisibilityToClients();
238 }
239
240 // Allow for state changes and animation to be applied if:
241 // * token is transitioning visibility state
242 // * or the token was marked as hidden and is exiting before we had a chance to play the
243 // transition animation
244 // * or this is an opening app and windows are being replaced.
245 boolean visibilityChanged = false;
246 if (hidden == visible || (hidden && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700247 final AccessibilityController accessibilityController = mService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700248 boolean changed = false;
249 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
250 "Changing app " + this + " hidden=" + hidden + " performLayout=" + performLayout);
251
252 boolean runningAppAnimation = false;
253
254 if (transit != AppTransition.TRANSIT_UNSET) {
255 if (mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
256 mAppAnimator.setNullAnimation();
257 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700258 if (mService.applyAnimationLocked(this, lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700259 delayed = runningAppAnimation = true;
260 }
261 final WindowState window = findMainWindow();
262 //TODO (multidisplay): Magnification is supported only for the default display.
263 if (window != null && accessibilityController != null
264 && window.getDisplayId() == DEFAULT_DISPLAY) {
265 accessibilityController.onAppWindowTransitionLocked(window, transit);
266 }
267 changed = true;
268 }
269
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700270 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700271 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700272 final WindowState win = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700273 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700274 }
275
276 hidden = hiddenRequested = !visible;
277 visibilityChanged = true;
278 if (!visible) {
279 stopFreezingScreen(true, true);
280 } else {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700281 // If we are being set visible, and the starting window is not yet displayed,
282 // then make sure it doesn't get displayed.
283 if (startingWindow != null && !startingWindow.isDrawnLw()) {
284 startingWindow.mPolicyVisibility = false;
285 startingWindow.mPolicyVisibilityAfterAnim = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700286 }
287 }
288
289 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setVisibility: " + this
290 + ": hidden=" + hidden + " hiddenRequested=" + hiddenRequested);
291
292 if (changed) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700293 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700294 if (performLayout) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700295 mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700296 false /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700297 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700298 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700299 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700300 }
301 }
302
303 if (mAppAnimator.animation != null) {
304 delayed = true;
305 }
306
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700307 for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
308 if (((WindowState) mChildren.get(i)).isWindowAnimationSet()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700309 delayed = true;
310 }
311 }
312
313 if (visibilityChanged) {
314 if (visible && !delayed) {
315 // The token was made immediately visible, there will be no entrance animation.
316 // We need to inform the client the enter animation was finished.
317 mEnteringAnimation = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700318 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700319 }
320
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700321 if (!mService.mClosingApps.contains(this) && !mService.mOpeningApps.contains(this)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700322 // The token is not closing nor opening, so even if there is an animation set, that
323 // doesn't mean that it goes through the normal app transition cycle so we have
324 // to inform the docked controller about visibility change.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700325 mService.getDefaultDisplayContentLocked().getDockedDividerController()
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700326 .notifyAppVisibilityChanged();
327 }
328 }
329
330 return delayed;
331 }
332
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800333 WindowState findMainWindow() {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700334 WindowState candidate = null;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700335 int j = mChildren.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800336 while (j > 0) {
337 j--;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700338 final WindowState win = (WindowState) mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700339 final int type = win.mAttrs.type;
340 // No need to loop through child window as base application and starting types can't be
341 // child windows.
342 if (type == TYPE_BASE_APPLICATION || type == TYPE_APPLICATION_STARTING) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700343 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900344 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700345 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800346 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700347 candidate = win;
348 } else {
349 return win;
350 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800351 }
352 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700353 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800354 }
355
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800356 boolean windowsAreFocusable() {
357 return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800358 }
359
Wale Ogunwale571771c2016-08-26 13:18:50 -0700360 @Override
Wale Ogunwale44f21802016-09-02 12:49:48 -0700361 boolean isVisible() {
362 if (hidden) {
363 // TODO: Should this be checking hiddenRequested instead of hidden?
364 return false;
365 }
366 return super.isVisible();
367 }
368
369 @Override
Wale Ogunwale571771c2016-08-26 13:18:50 -0700370 void removeIfPossible() {
Craig Mautnere3119b72015-01-20 15:02:36 -0800371 mIsExiting = false;
372 removeAllWindows();
Wale Ogunwale571771c2016-08-26 13:18:50 -0700373 if (mTask != null) {
374 mTask.detachChild(this);
Craig Mautnere3119b72015-01-20 15:02:36 -0800375 }
376 }
377
Chong Zhange05bcb12016-07-26 17:47:29 -0700378 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700379 boolean wallpaperMightChange = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700380 for (int i = mChildren.size() - 1; i >= 0; i--) {
381 final WindowState win = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700382 wallpaperMightChange |= win.clearAnimatingFlags();
Chong Zhange05bcb12016-07-26 17:47:29 -0700383 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700384 if (wallpaperMightChange) {
385 requestUpdateWallpaperIfNeeded();
386 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700387 }
388
Robert Carre12aece2016-02-02 22:43:27 -0800389 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700390 destroySurfaces(false /*cleanupOnResume*/);
391 }
392
393 /**
394 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
395 * the client has finished with them.
396 *
397 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
398 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
399 * others so that they are ready to be reused. If set to false (common case), destroy all
400 * surfaces that's eligible, if the app is already stopped.
401 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700402 private void destroySurfaces(boolean cleanupOnResume) {
Robert Carre12aece2016-02-02 22:43:27 -0800403 final DisplayContentList displayList = new DisplayContentList();
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700404 for (int i = mChildren.size() - 1; i >= 0; i--) {
405 final WindowState win = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700406 final boolean destroyed = win.destroySurface(cleanupOnResume, mAppStopped);
Chong Zhangeb665572016-05-09 18:28:27 -0700407
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700408 if (destroyed) {
409 final DisplayContent displayContent = win.getDisplayContent();
410 if (displayContent != null && !displayList.contains(displayContent)) {
411 displayList.add(displayContent);
412 }
Robert Carre12aece2016-02-02 22:43:27 -0800413 }
Robert Carre12aece2016-02-02 22:43:27 -0800414 }
415 for (int i = 0; i < displayList.size(); i++) {
416 final DisplayContent displayContent = displayList.get(i);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700417 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Robert Carre12aece2016-02-02 22:43:27 -0800418 displayContent.layoutNeeded = true;
419 }
420 }
421
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800422 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700423 * Notify that the app is now resumed, and it was not stopped before, perform a clean
424 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800425 */
Chong Zhangad24f962016-08-25 12:12:33 -0700426 void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
427 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
428 + " allowSavedSurface=" + allowSavedSurface + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700429 mAppStopped = false;
430 if (!wasStopped) {
431 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800432 }
Chong Zhangad24f962016-08-25 12:12:33 -0700433 if (!allowSavedSurface) {
434 destroySavedSurfaces();
435 }
Robert Carre12aece2016-02-02 22:43:27 -0800436 }
437
Chong Zhangbef461f2015-10-27 11:38:24 -0700438 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700439 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
440 * keeping alive in case they were still being used.
441 */
442 void notifyAppStopped() {
443 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
444 mAppStopped = true;
445 destroySurfaces();
446 // Remove any starting window that was added for this app if they are still around.
447 mTask.mService.scheduleRemoveStartingWindowLocked(this);
448 }
449
450 /**
Chong Zhangbef461f2015-10-27 11:38:24 -0700451 * Checks whether we should save surfaces for this app.
452 *
453 * @return true if the surfaces should be saved, false otherwise.
454 */
455 boolean shouldSaveSurface() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800456 // We want to save surface if the app's windows are "allDrawn".
457 // (If we started entering animation early with saved surfaces, allDrawn
458 // should have been restored to true. So we'll save again in that case
459 // even if app didn't actually finish drawing.)
460 return allDrawn;
Robert Carr13f7be9e2015-12-02 18:39:45 -0800461 }
462
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700463 private boolean canRestoreSurfaces() {
464 for (int i = mChildren.size() -1; i >= 0; i--) {
465 final WindowState w = (WindowState) mChildren.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700466 if (w.canRestoreSurface()) {
Robert Carr13f7be9e2015-12-02 18:39:45 -0800467 return true;
468 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700469 }
470 return false;
471 }
472
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700473 private void clearWasVisibleBeforeClientHidden() {
474 for (int i = mChildren.size() - 1; i >= 0; i--) {
475 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700476 w.clearWasVisibleBeforeClientHidden();
Chong Zhang92147042016-05-09 12:47:11 -0700477 }
478 }
479
Chong Zhang8e4bda92016-05-04 15:08:18 -0700480 /**
481 * Whether the app has some window that is invisible in layout, but
482 * animating with saved surface.
483 */
484 boolean isAnimatingInvisibleWithSavedSurface() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700485 for (int i = mChildren.size() - 1; i >= 0; i--) {
486 final WindowState w = (WindowState) mChildren.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700487 if (w.isAnimatingInvisibleWithSavedSurface()) {
488 return true;
489 }
490 }
491 return false;
492 }
493
494 /**
495 * Hide all window surfaces that's still invisible in layout but animating
496 * with a saved surface, and mark them destroying.
497 */
498 void stopUsingSavedSurfaceLocked() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700499 for (int i = mChildren.size() - 1; i >= 0; i--) {
500 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700501 w.stopUsingSavedSurface();
Chong Zhang8e4bda92016-05-04 15:08:18 -0700502 }
503 destroySurfaces();
504 }
505
Chong Zhangf58631a2016-05-24 16:02:10 -0700506 void markSavedSurfaceExiting() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700507 for (int i = mChildren.size() - 1; i >= 0; i--) {
508 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700509 w.markSavedSurfaceExiting();
Chong Zhangf58631a2016-05-24 16:02:10 -0700510 }
511 }
512
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700513 void restoreSavedSurfaceForInterestingWindows() {
Chong Zhang92147042016-05-09 12:47:11 -0700514 if (!canRestoreSurfaces()) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700515 clearWasVisibleBeforeClientHidden();
Chong Zhangbef461f2015-10-27 11:38:24 -0700516 return;
517 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700518
519 // Check if all interesting windows are drawn and we can mark allDrawn=true.
520 int interestingNotDrawn = -1;
521
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700522 for (int i = mChildren.size() - 1; i >= 0; i--) {
523 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700524 interestingNotDrawn = w.restoreSavedSurfaceForInterestingWindow();
Chong Zhangbef461f2015-10-27 11:38:24 -0700525 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800526
Chong Zhang92147042016-05-09 12:47:11 -0700527 if (!allDrawn) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700528 allDrawn = (interestingNotDrawn == 0);
Chong Zhang92147042016-05-09 12:47:11 -0700529 if (allDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700530 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Chong Zhang92147042016-05-09 12:47:11 -0700531 }
532 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700533 clearWasVisibleBeforeClientHidden();
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800534
535 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700536 "restoreSavedSurfaceForInterestingWindows: " + this + " allDrawn=" + allDrawn
537 + " interestingNotDrawn=" + interestingNotDrawn);
Chong Zhangbef461f2015-10-27 11:38:24 -0700538 }
539
540 void destroySavedSurfaces() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700541 for (int i = mChildren.size() - 1; i >= 0; i--) {
542 final WindowState win = (WindowState) mChildren.get(i);
Robert Carr13f7be9e2015-12-02 18:39:45 -0800543 win.destroySavedSurface();
Chong Zhangbef461f2015-10-27 11:38:24 -0700544 }
Chong Zhang92147042016-05-09 12:47:11 -0700545 }
546
547 void clearAllDrawn() {
548 allDrawn = false;
549 deferClearAllDrawn = false;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700550 allDrawnExcludingSaved = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700551 }
552
Wale Ogunwale98e70d02014-11-10 12:12:27 -0800553 @Override
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700554 void removeWindow(WindowState win) {
555 super.removeWindow(win);
556
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700557 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700558 if (startingWindow == win) {
559 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700560 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700561 } else if (mChildren.size() == 0 && startingData != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700562 // If this is the last window and we had requested a starting transition window,
563 // well there is no point now.
564 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
565 startingData = null;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700566 } else if (mChildren.size() == 1 && startingView != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700567 // If this is the last window except for a starting transition window,
568 // we need to get rid of the starting transition.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700569 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700570 }
571 }
572
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700573 void removeDeadWindows() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700574 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
575 WindowState win = (WindowState) mChildren.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800576 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700577 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700578 "removeDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800579 // Set mDestroying, we don't want any animation or delayed removal here.
580 win.mDestroying = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700581 // Also removes child windows.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700582 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800583 }
584 }
585 }
586
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700587 boolean hasWindowsAlive() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700588 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700589 // No need to loop through child windows as the answer should be the same as that of the
590 // parent window.
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700591 if (!((WindowState) mChildren.get(i)).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700592 return true;
593 }
594 }
595 return false;
596 }
597
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700598 void setWillReplaceWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700599 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
600 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800601
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700602 for (int i = mChildren.size() - 1; i >= 0; i--) {
603 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700604 w.setWillReplaceWindow(animate);
Robert Carra1eb4392015-12-10 12:43:51 -0800605 }
606 if (animate) {
607 // Set-up dummy animation so we can start treating windows associated with this
608 // token like they are in transition before the new app window is ready for us to
609 // run the real transition animation.
610 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700611 "setWillReplaceWindow() Setting dummy animation on: " + this);
Robert Carra1eb4392015-12-10 12:43:51 -0800612 mAppAnimator.setDummyAnimation();
613 }
614 }
615
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700616 void setWillReplaceChildWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700617 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800618 + " with replacing child windows.");
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700619 for (int i = mChildren.size() - 1; i >= 0; i--) {
620 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700621 w.setWillReplaceChildWindows();
Robert Carr23fa16b2016-01-13 13:19:58 -0800622 }
623 }
624
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700625 void clearWillReplaceWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700626 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
627 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800628
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700629 for (int i = mChildren.size() - 1; i >= 0; i--) {
630 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700631 w.clearWillReplaceWindow();
Chong Zhangf596cd52016-01-05 13:42:44 -0800632 }
633 }
634
Chong Zhang4d7369a2016-04-25 16:09:14 -0700635 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700636 for (int i = mChildren.size() - 1; i >= 0; i--) {
637 final WindowState w = (WindowState) mChildren.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -0700638 w.requestUpdateWallpaperIfNeeded();
639 }
640 }
641
Chong Zhangd78ddb42016-03-02 17:01:14 -0800642 boolean isRelaunching() {
643 return mPendingRelaunchCount > 0;
644 }
645
646 void startRelaunching() {
647 if (canFreezeBounds()) {
648 freezeBounds();
649 }
650 mPendingRelaunchCount++;
651 }
652
653 void finishRelaunching() {
654 if (canFreezeBounds()) {
655 unfreezeBounds();
656 }
657 if (mPendingRelaunchCount > 0) {
658 mPendingRelaunchCount--;
659 }
660 }
661
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700662 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700663 if (mPendingRelaunchCount == 0) {
664 return;
665 }
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700666 if (canFreezeBounds()) {
667 unfreezeBounds();
668 }
669 mPendingRelaunchCount = 0;
670 }
671
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700672 @Override
Robert Carra1eb4392015-12-10 12:43:51 -0800673 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700674 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700675
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700676 boolean gotReplacementWindow = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700677 for (int i = mChildren.size() - 1; i >= 0; i--) {
678 final WindowState candidate = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700679 gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
680 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700681
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700682 // if we got a replacement window, reset the timeout to give drawing more time
683 if (gotReplacementWindow) {
684 mService.scheduleWindowReplacementTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -0800685 }
Robert Carra1eb4392015-12-10 12:43:51 -0800686 }
687
688 boolean waitingForReplacement() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700689 for (int i = mChildren.size() - 1; i >= 0; i--) {
690 final WindowState candidate = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700691 if (candidate.waitingForReplacement()) {
Robert Carra1eb4392015-12-10 12:43:51 -0800692 return true;
693 }
694 }
695 return false;
696 }
697
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700698 void onWindowReplacementTimeout() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700699 for (int i = mChildren.size() - 1; i >= 0; --i) {
700 ((WindowState) mChildren.get(i)).onWindowReplacementTimeout();
Robert Carra1eb4392015-12-10 12:43:51 -0800701 }
702 }
703
Chong Zhangd78ddb42016-03-02 17:01:14 -0800704 private boolean canFreezeBounds() {
705 // For freeform windows, we can't freeze the bounds at the moment because this would make
706 // the resizing unresponsive.
707 return mTask != null && !mTask.inFreeformWorkspace();
708 }
709
Jorim Jaggi0429f352015-12-22 16:29:16 +0100710 /**
711 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
712 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
713 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
714 * with a queue.
715 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800716 private void freezeBounds() {
Jorim Jaggi0429f352015-12-22 16:29:16 +0100717 mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700718
719 if (mTask.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
720 // We didn't call prepareFreezingBounds on the task, so use the current value.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700721 final Configuration config = new Configuration(mService.mCurConfiguration);
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700722 config.updateFrom(mTask.mOverrideConfig);
723 mFrozenMergedConfig.offer(config);
724 } else {
725 mFrozenMergedConfig.offer(new Configuration(mTask.mPreparedFrozenMergedConfig));
726 }
727 mTask.mPreparedFrozenMergedConfig.setToDefaults();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100728 }
729
730 /**
731 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
732 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800733 private void unfreezeBounds() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700734 if (!mFrozenBounds.isEmpty()) {
735 mFrozenBounds.remove();
736 }
737 if (!mFrozenMergedConfig.isEmpty()) {
738 mFrozenMergedConfig.remove();
739 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700740 for (int i = mChildren.size() - 1; i >= 0; i--) {
741 final WindowState win = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700742 win.onUnfreezeBounds();
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100743 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700744 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100745 }
746
Robert Carr91b228092016-06-28 17:32:37 -0700747 void addSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
748 mSurfaceViewBackgrounds.add(background);
749 }
750
751 void removeSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
752 mSurfaceViewBackgrounds.remove(background);
753 updateSurfaceViewBackgroundVisibilities();
754 }
755
756 // We use DimLayers behind SurfaceViews to prevent holes while resizing and creating.
757 // However, we need to ensure one SurfaceView doesn't cover another when they are both placed
758 // below the main app window (as traditionally a SurfaceView which is never drawn
759 // to is totally translucent). So we look at all our SurfaceView backgrounds and only enable
760 // the background for the SurfaceView with lowest Z order
761 void updateSurfaceViewBackgroundVisibilities() {
762 WindowSurfaceController.SurfaceControlWithBackground bottom = null;
763 int bottomLayer = Integer.MAX_VALUE;
764 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
765 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
766 if (sc.mVisible && sc.mLayer < bottomLayer) {
767 bottomLayer = sc.mLayer;
768 bottom = sc;
769 }
770 }
771 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
772 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
773 sc.updateBackgroundVisibility(sc != bottom);
774 }
775 }
776
Jorim Jaggi6626f542016-08-22 13:08:44 -0700777 /**
778 * See {@link WindowManagerService#overridePlayingAppAnimationsLw}
779 */
780 void overridePlayingAppAnimations(Animation a) {
781 if (mAppAnimator.isAnimating()) {
782 final WindowState win = findMainWindow();
783 final int width = win.mContainingFrame.width();
784 final int height = win.mContainingFrame.height();
785 mAppAnimator.setAnimation(a, width, height, false, STACK_CLIP_NONE);
786 }
787 }
788
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700789 void resetJustMovedInStack() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700790 for (int i = mChildren.size() - 1; i >= 0; i--) {
791 ((WindowState) mChildren.get(i)).resetJustMovedInStack();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700792 }
793 }
794
795 void notifyMovedInStack() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700796 for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
797 final WindowState win = (WindowState) mChildren.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700798 win.notifyMovedInStack();
799 }
800 }
801
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700802 void setAppLayoutChanges(int changes, String reason, int displayId) {
803 final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700804 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700805 // Child windows will be on the same display as their parents.
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700806 if (displayId == ((WindowState) mChildren.get(i)).getDisplayId()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700807 windowAnimator.setPendingLayoutChanges(displayId, changes);
808 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700809 mService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700810 reason, windowAnimator.getPendingLayoutChanges(displayId));
811 }
812 break;
813 }
814 }
815 }
816
817 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700818 for (int i = mChildren.size() - 1; i >= 0; i--) {
819 final WindowState win = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700820 if (win.removeReplacedWindowIfNeeded(replacement)) {
821 return;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700822 }
823 }
824 }
825
826 void startFreezingScreen() {
827 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700828 + hidden + " freezing=" + mAppAnimator.freezingScreen + " hiddenRequested="
829 + hiddenRequested);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700830 if (!hiddenRequested) {
831 if (!mAppAnimator.freezingScreen) {
832 mAppAnimator.freezingScreen = true;
833 mAppAnimator.lastFreezeDuration = 0;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700834 mService.mAppsFreezingScreen++;
835 if (mService.mAppsFreezingScreen == 1) {
836 mService.startFreezingDisplayLocked(false, 0, 0);
837 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
838 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700839 }
840 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700841 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700842 for (int i = 0; i < count; i++) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700843 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700844 w.onStartFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700845 }
846 }
847 }
848
849 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
850 if (!mAppAnimator.freezingScreen) {
851 return;
852 }
853 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700854 final int count = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700855 boolean unfrozeWindows = false;
856 for (int i = 0; i < count; i++) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700857 final WindowState w = (WindowState) mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700858 unfrozeWindows |= w.onStopFreezingScreen();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700859 }
860 if (force || unfrozeWindows) {
861 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
862 mAppAnimator.freezingScreen = false;
863 mAppAnimator.lastFreezeDuration =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700864 (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime);
865 mService.mAppsFreezingScreen--;
866 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700867 }
868 if (unfreezeSurfaceNow) {
869 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700870 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700871 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700872 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700873 }
874 }
875
876 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700877 final AppWindowToken fromToken = mService.findAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700878 if (fromToken == null) {
879 return false;
880 }
881
882 final WindowState tStartingWindow = fromToken.startingWindow;
883 if (tStartingWindow != null && fromToken.startingView != null) {
884 // In this case, the starting icon has already been displayed, so start
885 // letting windows get shown immediately without any more transitions.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700886 mService.mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700887
888 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
889 + " from " + fromToken + " to " + this);
890
891 final long origId = Binder.clearCallingIdentity();
892
893 // Transfer the starting window over to the new token.
894 startingData = fromToken.startingData;
895 startingView = fromToken.startingView;
896 startingDisplayed = fromToken.startingDisplayed;
897 fromToken.startingDisplayed = false;
898 startingWindow = tStartingWindow;
899 reportedVisible = fromToken.reportedVisible;
900 fromToken.startingData = null;
901 fromToken.startingView = null;
902 fromToken.startingWindow = null;
903 fromToken.startingMoved = true;
904 tStartingWindow.mToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700905 tStartingWindow.mAppToken = this;
906
907 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
908 "Removing starting window: " + tStartingWindow);
909 tStartingWindow.getWindowList().remove(tStartingWindow);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700910 mService.mWindowsChanged = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700911 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
912 "Removing starting " + tStartingWindow + " from " + fromToken);
913 fromToken.removeWindow(tStartingWindow);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700914 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700915
916 // Propagate other interesting state between the tokens. If the old token is displayed,
917 // we should immediately force the new one to be displayed. If it is animating, we need
918 // to move that animation to the new one.
919 if (fromToken.allDrawn) {
920 allDrawn = true;
921 deferClearAllDrawn = fromToken.deferClearAllDrawn;
922 }
923 if (fromToken.firstWindowDrawn) {
924 firstWindowDrawn = true;
925 }
926 if (!fromToken.hidden) {
927 hidden = false;
928 hiddenRequested = false;
929 }
930 if (clientHidden != fromToken.clientHidden) {
931 clientHidden = fromToken.clientHidden;
932 sendAppVisibilityToClients();
933 }
934 fromToken.mAppAnimator.transferCurrentAnimation(
935 mAppAnimator, tStartingWindow.mWinAnimator);
936
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700937 mService.updateFocusedWindowLocked(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700938 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700939 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
940 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700941 Binder.restoreCallingIdentity(origId);
942 return true;
943 } else if (fromToken.startingData != null) {
944 // The previous app was getting ready to show a
945 // starting window, but hasn't yet done so. Steal it!
946 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
947 "Moving pending starting from " + fromToken + " to " + this);
948 startingData = fromToken.startingData;
949 fromToken.startingData = null;
950 fromToken.startingMoved = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700951 final Message m = mService.mH.obtainMessage(H.ADD_STARTING, this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700952 // Note: we really want to do sendMessageAtFrontOfQueue() because we want to process the
953 // message ASAP, before any other queued messages.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700954 mService.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700955 return true;
956 }
957
958 final AppWindowAnimator tAppAnimator = fromToken.mAppAnimator;
959 final AppWindowAnimator wAppAnimator = mAppAnimator;
960 if (tAppAnimator.thumbnail != null) {
961 // The old token is animating with a thumbnail, transfer that to the new token.
962 if (wAppAnimator.thumbnail != null) {
963 wAppAnimator.thumbnail.destroy();
964 }
965 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
966 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
967 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
968 tAppAnimator.thumbnail = null;
969 }
970 return false;
971 }
972
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700973 boolean isLastWindow(WindowState win) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700974 return mChildren.size() == 1 && mChildren.get(0) == win;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700975 }
976
977 void setAllAppWinAnimators() {
978 final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
979 allAppWinAnimators.clear();
980
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700981 final int windowsCount = mChildren.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700982 for (int j = 0; j < windowsCount; j++) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700983 ((WindowState) mChildren.get(j)).addWinAnimatorToList(allAppWinAnimators);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700984 }
985 }
986
Wale Ogunwale51362492016-09-08 17:49:17 -0700987 /**
988 * We override because this class doesn't want its children affecting its reported orientation
989 * in anyway.
990 */
991 @Override
992 int getOrientation() {
993 if (hidden || hiddenRequested) {
994 return SCREEN_ORIENTATION_UNSET;
995 }
996 return mOrientation;
997 }
998
Craig Mautnerdbb79912012-03-01 18:59:14 -0800999 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001000 AppWindowToken asAppWindowToken() {
1001 // I am an app window token!
1002 return this;
1003 }
1004
1005 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -07001006 boolean fillsParent() {
1007 return mFillsParent;
1008 }
1009
1010 void setFillsParent(boolean fillsParent) {
1011 mFillsParent = fillsParent;
1012 }
1013
1014 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001015 void dump(PrintWriter pw, String prefix) {
1016 super.dump(pw, prefix);
1017 if (appToken != null) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001018 pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001019 }
Craig Mautner83162a92015-01-26 14:43:30 -08001020 pw.print(prefix); pw.print("task="); pw.println(mTask);
Wale Ogunwale51362492016-09-08 17:49:17 -07001021 pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
1022 pw.print(" mOrientation="); pw.println(mOrientation);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001023 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
1024 pw.print(" clientHidden="); pw.print(clientHidden);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07001025 pw.print(" reportedDrawn="); pw.print(reportedDrawn);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001026 pw.print(" reportedVisible="); pw.println(reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07001027 if (paused) {
1028 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001029 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001030 if (mAppStopped) {
1031 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
1032 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001033 if (numInterestingWindows != 0 || numDrawnWindows != 0
Craig Mautner6fbda632012-07-03 09:26:39 -07001034 || allDrawn || mAppAnimator.allDrawn) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001035 pw.print(prefix); pw.print("numInterestingWindows=");
1036 pw.print(numInterestingWindows);
1037 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
1038 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07001039 pw.print(" allDrawn="); pw.print(allDrawn);
1040 pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
1041 pw.println(")");
1042 }
1043 if (inPendingTransaction) {
1044 pw.print(prefix); pw.print("inPendingTransaction=");
1045 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001046 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08001047 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001048 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
1049 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08001050 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08001051 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001052 }
1053 if (startingWindow != null || startingView != null
1054 || startingDisplayed || startingMoved) {
1055 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
1056 pw.print(" startingView="); pw.print(startingView);
1057 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001058 pw.print(" startingMoved="); pw.println(startingMoved);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001059 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01001060 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001061 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001062 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08001063 }
1064 if (mPendingRelaunchCount != 0) {
1065 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01001066 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001067 }
1068
1069 @Override
1070 public String toString() {
1071 if (stringName == null) {
1072 StringBuilder sb = new StringBuilder();
1073 sb.append("AppWindowToken{");
1074 sb.append(Integer.toHexString(System.identityHashCode(this)));
1075 sb.append(" token="); sb.append(token); sb.append('}');
1076 stringName = sb.toString();
1077 }
1078 return stringName;
1079 }
Jeff Browne9bdb312012-04-05 15:30:10 -07001080}