blob: df212bcacc1a6b3ba8f4958b1a178a0c3941b4b8 [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 Ogunwale9f25bee2016-08-02 07:23:47 -070020import static android.view.Display.DEFAULT_DISPLAY;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080021import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070022import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
23import static android.view.WindowManagerPolicy.TRANSIT_ENTER;
24import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
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_LAYERS;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
30import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
Wale Ogunwale9017ec02016-02-25 08:55:25 -080032import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080033import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
34import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
35import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
36import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang92147042016-05-09 12:47:11 -070037import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
Jorim Jaggi6626f542016-08-22 13:08:44 -070038import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070039import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
40import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
41import static com.android.server.wm.WindowManagerService.logWithStack;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080042
Jeff Brown4532e612012-04-05 14:27:12 -070043import com.android.server.input.InputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080044import com.android.server.wm.WindowManagerService.H;
45
Filip Gruszczynskia590c992015-11-25 16:45:26 -080046import android.annotation.NonNull;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080047import android.content.pm.ActivityInfo;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070048import android.content.res.Configuration;
Jorim Jaggi0429f352015-12-22 16:29:16 +010049import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070050import android.os.Binder;
51import android.os.IBinder;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080052import android.os.Message;
53import android.os.RemoteException;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070054import android.os.SystemClock;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080055import android.util.Slog;
56import android.view.IApplicationToken;
57import android.view.View;
58import android.view.WindowManager;
Jorim Jaggi6626f542016-08-22 13:08:44 -070059import android.view.animation.Animation;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080060
61import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +010062import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080063import java.util.ArrayList;
64
65class AppTokenList extends ArrayList<AppWindowToken> {
66}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080067
68/**
69 * Version of WindowToken that is specifically for a particular application (or
70 * really activity) that is displaying windows.
71 */
Craig Mautnere32c3072012-03-12 15:25:35 -070072class AppWindowToken extends WindowToken {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080073 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
74
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080075 // Non-null only for application tokens.
76 final IApplicationToken appToken;
77
Filip Gruszczynskia590c992015-11-25 16:45:26 -080078 @NonNull final AppWindowAnimator mAppAnimator;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070079
Dianne Hackborne30e02f2014-05-27 18:24:45 -070080 final boolean voiceInteraction;
81
Craig Mautner83162a92015-01-26 14:43:30 -080082 Task mTask;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080083 boolean appFullscreen;
84 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Craig Mautner4c5eb222013-11-18 12:59:05 -080085 boolean layoutConfigChanges;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -070086 boolean showForAllUsers;
Yorke Lee0e852472016-06-15 10:03:18 -070087 int targetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -070088
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080089 // The input dispatching timeout for this application token in nanoseconds.
90 long inputDispatchingTimeoutNanos;
91
92 // These are used for determining when all windows associated with
93 // an activity have been drawn, so they can be made visible together
94 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -070095 // initialize so that it doesn't match mTransactionSequence which is an int.
96 long lastTransactionSequence = Long.MIN_VALUE;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080097 int numInterestingWindows;
98 int numDrawnWindows;
99 boolean inPendingTransaction;
100 boolean allDrawn;
Craig Mautner7636dfb2012-11-16 15:24:11 -0800101 // Set to true when this app creates a surface while in the middle of an animation. In that
102 // case do not clear allDrawn until the animation completes.
103 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800104
Chong Zhang8e4bda92016-05-04 15:08:18 -0700105 // These are to track the app's real drawing status if there were no saved surfaces.
106 boolean allDrawnExcludingSaved;
107 int numInterestingWindowsExcludingSaved;
108 int numDrawnWindowsExclusingSaved;
109
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800110 // Is this window's surface needed? This is almost like hidden, except
111 // it will sometimes be true a little earlier: when the token has
112 // been shown, but is still waiting for its app transition to execute
113 // before making its windows shown.
114 boolean hiddenRequested;
115
116 // Have we told the window clients to hide themselves?
117 boolean clientHidden;
118
119 // Last visibility state we reported to the app token.
120 boolean reportedVisible;
121
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700122 // Last drawn state we reported to the app token.
123 boolean reportedDrawn;
124
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800125 // Set to true when the token has been removed from the window mgr.
126 boolean removed;
127
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800128 // Information about an application starting window if displayed.
129 StartingData startingData;
130 WindowState startingWindow;
131 View startingView;
132 boolean startingDisplayed;
133 boolean startingMoved;
134 boolean firstWindowDrawn;
135
136 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700137 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800138
Craig Mautner799bc1d2015-01-14 10:33:48 -0800139 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800140
Craig Mautnerbb742462014-07-07 15:28:55 -0700141 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700142 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700143
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800144 boolean mAlwaysFocusable;
145
Robert Carre12aece2016-02-02 22:43:27 -0800146 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700147 int mRotationAnimationHint;
Chong Zhangd78ddb42016-03-02 17:01:14 -0800148 int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800149
Robert Carr91b228092016-06-28 17:32:37 -0700150 private ArrayList<WindowSurfaceController.SurfaceControlWithBackground> mSurfaceViewBackgrounds =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700151 new ArrayList<>();
Robert Carr91b228092016-06-28 17:32:37 -0700152
Jorim Jaggi0429f352015-12-22 16:29:16 +0100153 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700154 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100155
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700156 AppWindowToken(WindowManagerService service, IApplicationToken _token, boolean _voiceInteraction) {
157 super(service, _token.asBinder(), WindowManager.LayoutParams.TYPE_APPLICATION, true);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800158 appToken = _token;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700159 voiceInteraction = _voiceInteraction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800160 mInputApplicationHandle = new InputApplicationHandle(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700161 mAppAnimator = new AppWindowAnimator(this, service);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800162 }
163
164 void sendAppVisibilityToClients() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700165 final int N = windows.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800166 for (int i=0; i<N; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700167 WindowState win = windows.get(i);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800168 if (win == startingWindow && clientHidden) {
169 // Don't hide the starting window.
170 continue;
171 }
172 try {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800173 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800174 "Setting visibility of " + win + ": " + (!clientHidden));
175 win.mClient.dispatchAppVisibility(!clientHidden);
176 } catch (RemoteException e) {
177 }
178 }
179 }
180
Chong Zhang92147042016-05-09 12:47:11 -0700181 void setVisibleBeforeClientHidden() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700182 for (int i = windows.size() - 1; i >= 0; i--) {
183 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700184 w.setVisibleBeforeClientHidden();
185 }
186 }
187
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800188 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
189 firstWindowDrawn = true;
190
191 // We now have a good window to show, remove dead placeholders
192 removeAllDeadWindows();
193
194 if (startingData != null) {
195 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
196 + win.mToken + ": first real window is shown, no animation");
197 // If this initial window is animating, stop it -- we will do an animation to reveal
198 // it from behind the starting window, so there is no need for it to also be doing its
199 // own stuff.
200 winAnimator.clearAnimation();
201 winAnimator.mService.mFinishedStarting.add(this);
202 winAnimator.mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
203 }
204 updateReportedVisibilityLocked();
205 }
206
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800207 void updateReportedVisibilityLocked() {
208 if (appToken == null) {
209 return;
210 }
211
212 int numInteresting = 0;
213 int numVisible = 0;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700214 int numDrawn = 0;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800215 boolean nowGone = true;
216
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800217 if (DEBUG_VISIBILITY) Slog.v(TAG,
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700218 "Update reported visibility: " + this);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700219 final int N = windows.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800220 for (int i=0; i<N; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700221 WindowState win = windows.get(i);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800222 if (win == startingWindow || win.mAppFreezing
223 || win.mViewVisibility != View.VISIBLE
224 || win.mAttrs.type == TYPE_APPLICATION_STARTING
225 || win.mDestroying) {
226 continue;
227 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800228 if (DEBUG_VISIBILITY) {
229 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800230 + win.isDrawnLw()
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700231 + ", isAnimationSet=" + win.mWinAnimator.isAnimationSet());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800232 if (!win.isDrawnLw()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800233 Slog.v(TAG, "Not displayed: s=" +
Robert Carre6a83512015-11-03 16:09:21 -0800234 win.mWinAnimator.mSurfaceController
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800235 + " pv=" + win.mPolicyVisibility
Craig Mautner749a7bb2012-04-02 13:49:53 -0700236 + " mDrawState=" + win.mWinAnimator.mDrawState
Wale Ogunwale9d147902016-07-16 11:58:55 -0700237 + " ph=" + win.isParentWindowHidden()
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800238 + " th="
239 + (win.mAppToken != null
240 ? win.mAppToken.hiddenRequested : false)
Craig Mautnera2c77052012-03-26 12:14:43 -0700241 + " a=" + win.mWinAnimator.mAnimating);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800242 }
243 }
244 numInteresting++;
245 if (win.isDrawnLw()) {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700246 numDrawn++;
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700247 if (!win.mWinAnimator.isAnimationSet()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800248 numVisible++;
249 }
250 nowGone = false;
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700251 } else if (win.mWinAnimator.isAnimationSet()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800252 nowGone = false;
253 }
254 }
255
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700256 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800257 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700258 if (!nowGone) {
259 // If the app is not yet gone, then it can only become visible/drawn.
260 if (!nowDrawn) {
261 nowDrawn = reportedDrawn;
262 }
263 if (!nowVisible) {
264 nowVisible = reportedVisible;
265 }
266 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800267 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800268 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700269 if (nowDrawn != reportedDrawn) {
270 if (nowDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700271 Message m = mService.mH.obtainMessage(
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700272 H.REPORT_APPLICATION_TOKEN_DRAWN, this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700273 mService.mH.sendMessage(m);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700274 }
275 reportedDrawn = nowDrawn;
276 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800277 if (nowVisible != reportedVisible) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800278 if (DEBUG_VISIBILITY) Slog.v(
279 TAG, "Visibility changed in " + this
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800280 + ": vis=" + nowVisible);
281 reportedVisible = nowVisible;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700282 Message m = mService.mH.obtainMessage(
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800283 H.REPORT_APPLICATION_TOKEN_WINDOWS,
284 nowVisible ? 1 : 0,
285 nowGone ? 1 : 0,
286 this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700287 mService.mH.sendMessage(m);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800288 }
289 }
290
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700291 boolean setVisibility(WindowManager.LayoutParams lp,
292 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
293
294 boolean delayed = false;
295 inPendingTransaction = false;
296
297 if (clientHidden == visible) {
298 clientHidden = !visible;
299 sendAppVisibilityToClients();
300 }
301
302 // Allow for state changes and animation to be applied if:
303 // * token is transitioning visibility state
304 // * or the token was marked as hidden and is exiting before we had a chance to play the
305 // transition animation
306 // * or this is an opening app and windows are being replaced.
307 boolean visibilityChanged = false;
308 if (hidden == visible || (hidden && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700309 final AccessibilityController accessibilityController = mService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700310 boolean changed = false;
311 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
312 "Changing app " + this + " hidden=" + hidden + " performLayout=" + performLayout);
313
314 boolean runningAppAnimation = false;
315
316 if (transit != AppTransition.TRANSIT_UNSET) {
317 if (mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
318 mAppAnimator.setNullAnimation();
319 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700320 if (mService.applyAnimationLocked(this, lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700321 delayed = runningAppAnimation = true;
322 }
323 final WindowState window = findMainWindow();
324 //TODO (multidisplay): Magnification is supported only for the default display.
325 if (window != null && accessibilityController != null
326 && window.getDisplayId() == DEFAULT_DISPLAY) {
327 accessibilityController.onAppWindowTransitionLocked(window, transit);
328 }
329 changed = true;
330 }
331
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700332 final int windowsCount = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700333 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700334 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700335 if (win == startingWindow) {
336 // Starting window that's exiting will be removed when the animation finishes.
337 // Mark all relevant flags for that onExitAnimationDone will proceed all the way
338 // to actually remove it.
339 if (!visible && win.isVisibleNow() && mAppAnimator.isAnimating()) {
340 win.mAnimatingExit = true;
341 win.mRemoveOnExit = true;
342 win.mWindowRemovalAllowed = true;
343 }
344 continue;
345 }
346
347 //Slog.i(TAG_WM, "Window " + win + ": vis=" + win.isVisible());
348 //win.dump(" ");
349 if (visible) {
350 if (!win.isVisibleNow()) {
351 if (!runningAppAnimation) {
352 win.mWinAnimator.applyAnimationLocked(TRANSIT_ENTER, true);
353 //TODO (multidisplay): Magnification is supported only for the default
354 if (accessibilityController != null
355 && win.getDisplayId() == DEFAULT_DISPLAY) {
356 accessibilityController.onWindowTransitionLocked(win, TRANSIT_ENTER);
357 }
358 }
359 changed = true;
360 win.setDisplayLayoutNeeded();
361 }
362 } else if (win.isVisibleNow()) {
363 if (!runningAppAnimation) {
364 win.mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false);
365 //TODO (multidisplay): Magnification is supported only for the default
366 if (accessibilityController != null
367 && win.getDisplayId() == DEFAULT_DISPLAY) {
368 accessibilityController.onWindowTransitionLocked(win,TRANSIT_EXIT);
369 }
370 }
371 changed = true;
372 win.setDisplayLayoutNeeded();
373 }
374 }
375
376 hidden = hiddenRequested = !visible;
377 visibilityChanged = true;
378 if (!visible) {
379 stopFreezingScreen(true, true);
380 } else {
381 // If we are being set visible, and the starting window is
382 // not yet displayed, then make sure it doesn't get displayed.
383 WindowState swin = startingWindow;
384 if (swin != null && !swin.isDrawnLw()) {
385 swin.mPolicyVisibility = false;
386 swin.mPolicyVisibilityAfterAnim = false;
387 }
388 }
389
390 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setVisibility: " + this
391 + ": hidden=" + hidden + " hiddenRequested=" + hiddenRequested);
392
393 if (changed) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700394 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700395 if (performLayout) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700396 mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700397 false /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700398 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700399 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700400 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700401 }
402 }
403
404 if (mAppAnimator.animation != null) {
405 delayed = true;
406 }
407
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700408 for (int i = windows.size() - 1; i >= 0 && !delayed; i--) {
409 if (windows.get(i).mWinAnimator.isWindowAnimationSet()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700410 delayed = true;
411 }
412 }
413
414 if (visibilityChanged) {
415 if (visible && !delayed) {
416 // The token was made immediately visible, there will be no entrance animation.
417 // We need to inform the client the enter animation was finished.
418 mEnteringAnimation = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700419 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700420 }
421
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700422 if (!mService.mClosingApps.contains(this) && !mService.mOpeningApps.contains(this)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700423 // The token is not closing nor opening, so even if there is an animation set, that
424 // doesn't mean that it goes through the normal app transition cycle so we have
425 // to inform the docked controller about visibility change.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700426 mService.getDefaultDisplayContentLocked().getDockedDividerController()
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700427 .notifyAppVisibilityChanged();
428 }
429 }
430
431 return delayed;
432 }
433
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800434 WindowState findMainWindow() {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700435 WindowState candidate = null;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700436 int j = windows.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800437 while (j > 0) {
438 j--;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700439 WindowState win = windows.get(j);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800440 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
441 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700442 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900443 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700444 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800445 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700446 candidate = win;
447 } else {
448 return win;
449 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800450 }
451 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700452 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800453 }
454
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800455 boolean windowsAreFocusable() {
456 return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800457 }
458
Craig Mautner72669d12012-12-18 17:23:54 -0800459 boolean isVisible() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700460 final int N = windows.size();
Craig Mautner72669d12012-12-18 17:23:54 -0800461 for (int i=0; i<N; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700462 WindowState win = windows.get(i);
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700463 // If we're animating with a saved surface, we're already visible.
464 // Return true so that the alpha doesn't get cleared.
Craig Mautner72669d12012-12-18 17:23:54 -0800465 if (!win.mAppFreezing
Chong Zhang92147042016-05-09 12:47:11 -0700466 && (win.mViewVisibility == View.VISIBLE || win.isAnimatingWithSavedSurface()
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700467 || (win.mWinAnimator.isAnimationSet()
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700468 && !mService.mAppTransition.isTransitionSet()))
Filip Gruszczynski57f76f12015-11-04 16:10:54 -0800469 && !win.mDestroying
470 && win.isDrawnLw()) {
Craig Mautner72669d12012-12-18 17:23:54 -0800471 return true;
472 }
473 }
474 return false;
475 }
476
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700477 boolean isVisibleForUser() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700478 for (int j = windows.size() - 1; j >= 0; j--) {
479 final WindowState w = windows.get(j);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700480 if (!w.isHiddenFromUserLocked()) {
481 return true;
482 }
483 }
484 return false;
485 }
486
Craig Mautnere3119b72015-01-20 15:02:36 -0800487 void removeAppFromTaskLocked() {
488 mIsExiting = false;
489 removeAllWindows();
490
Craig Mautner83162a92015-01-26 14:43:30 -0800491 // Use local variable because removeAppToken will null out mTask.
492 final Task task = mTask;
Craig Mautnere3119b72015-01-20 15:02:36 -0800493 if (task != null) {
494 if (!task.removeAppToken(this)) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800495 Slog.e(TAG, "removeAppFromTaskLocked: token=" + this
Craig Mautnere3119b72015-01-20 15:02:36 -0800496 + " not found.");
497 }
498 task.mStack.mExitingAppTokens.remove(this);
499 }
500 }
501
Chong Zhange05bcb12016-07-26 17:47:29 -0700502 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700503 boolean wallpaperMightChange = false;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700504 for (int i = windows.size() - 1; i >= 0; i--) {
505 final WindowState win = windows.get(i);
Chong Zhange05bcb12016-07-26 17:47:29 -0700506 // We don't want to clear it out for windows that get replaced, because the
507 // animation depends on the flag to remove the replaced window.
508 //
509 // We also don't clear the mAnimatingExit flag for windows which have the
510 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
511 // by the client. We should let animation proceed and not clear this flag or
512 // they won't eventually be removed by WindowStateAnimator#finishExit.
513 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Chong Zhange05bcb12016-07-26 17:47:29 -0700514 // Clear mAnimating flag together with mAnimatingExit. When animation
515 // changes from exiting to entering, we need to clear this flag until the
516 // new animation gets applied, so that isAnimationStarting() becomes true
517 // until then.
518 // Otherwise applySurfaceChangesTransaction will faill to skip surface
519 // placement for this window during this period, one or more frame will
520 // show up with wrong position or scale.
Chong Zhangb0d26702016-08-12 16:03:29 -0700521 if (win.mAnimatingExit) {
522 win.mAnimatingExit = false;
523 wallpaperMightChange = true;
524 }
525 if (win.mWinAnimator.mAnimating) {
526 win.mWinAnimator.mAnimating = false;
527 wallpaperMightChange = true;
528 }
Wale Ogunwale3c0d44e2016-08-11 09:34:45 -0700529 if (win.mDestroying) {
530 win.mDestroying = false;
Chong Zhang12d266f2016-08-11 16:27:43 -0700531 mService.mDestroySurface.remove(win);
Chong Zhangb0d26702016-08-12 16:03:29 -0700532 wallpaperMightChange = true;
Wale Ogunwale3c0d44e2016-08-11 09:34:45 -0700533 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700534 }
535 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700536 if (wallpaperMightChange) {
537 requestUpdateWallpaperIfNeeded();
538 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700539 }
540
Robert Carre12aece2016-02-02 22:43:27 -0800541 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700542 destroySurfaces(false /*cleanupOnResume*/);
543 }
544
545 /**
546 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
547 * the client has finished with them.
548 *
549 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
550 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
551 * others so that they are ready to be reused. If set to false (common case), destroy all
552 * surfaces that's eligible, if the app is already stopped.
553 */
554
555 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700556 final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) windows.clone();
Robert Carre12aece2016-02-02 22:43:27 -0800557 final DisplayContentList displayList = new DisplayContentList();
558 for (int i = allWindows.size() - 1; i >= 0; i--) {
559 final WindowState win = allWindows.get(i);
Chong Zhangeb665572016-05-09 18:28:27 -0700560
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700561 if (!(mAppStopped || win.mWindowRemovalAllowed || cleanupOnResume)) {
Robert Carre12aece2016-02-02 22:43:27 -0800562 continue;
563 }
564
Chong Zhangeb665572016-05-09 18:28:27 -0700565 win.mWinAnimator.destroyPreservedSurfaceLocked();
566
567 if (!win.mDestroying) {
Chong Zhang5471e902016-02-12 15:34:10 -0800568 continue;
Robert Carre12aece2016-02-02 22:43:27 -0800569 }
570
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800571 if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + win
572 + " destroySurfaces: mAppStopped=" + mAppStopped
573 + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed
574 + " win.mRemoveOnExit=" + win.mRemoveOnExit);
575
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700576 if (!cleanupOnResume || win.mRemoveOnExit) {
577 win.destroyOrSaveSurface();
578 }
Robert Carre12aece2016-02-02 22:43:27 -0800579 if (win.mRemoveOnExit) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700580 win.remove();
Robert Carre12aece2016-02-02 22:43:27 -0800581 }
582 final DisplayContent displayContent = win.getDisplayContent();
583 if (displayContent != null && !displayList.contains(displayContent)) {
584 displayList.add(displayContent);
585 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700586 if (cleanupOnResume) {
587 win.requestUpdateWallpaperIfNeeded();
588 }
Robert Carre12aece2016-02-02 22:43:27 -0800589 win.mDestroying = false;
590 }
591 for (int i = 0; i < displayList.size(); i++) {
592 final DisplayContent displayContent = displayList.get(i);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700593 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Robert Carre12aece2016-02-02 22:43:27 -0800594 displayContent.layoutNeeded = true;
595 }
596 }
597
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800598 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700599 * Notify that the app is now resumed, and it was not stopped before, perform a clean
600 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800601 */
Chong Zhangad24f962016-08-25 12:12:33 -0700602 void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
603 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
604 + " allowSavedSurface=" + allowSavedSurface + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700605 mAppStopped = false;
606 if (!wasStopped) {
607 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800608 }
Chong Zhangad24f962016-08-25 12:12:33 -0700609 if (!allowSavedSurface) {
610 destroySavedSurfaces();
611 }
Robert Carre12aece2016-02-02 22:43:27 -0800612 }
613
Chong Zhangbef461f2015-10-27 11:38:24 -0700614 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700615 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
616 * keeping alive in case they were still being used.
617 */
618 void notifyAppStopped() {
619 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
620 mAppStopped = true;
621 destroySurfaces();
622 // Remove any starting window that was added for this app if they are still around.
623 mTask.mService.scheduleRemoveStartingWindowLocked(this);
624 }
625
626 /**
Chong Zhangbef461f2015-10-27 11:38:24 -0700627 * Checks whether we should save surfaces for this app.
628 *
629 * @return true if the surfaces should be saved, false otherwise.
630 */
631 boolean shouldSaveSurface() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800632 // We want to save surface if the app's windows are "allDrawn".
633 // (If we started entering animation early with saved surfaces, allDrawn
634 // should have been restored to true. So we'll save again in that case
635 // even if app didn't actually finish drawing.)
636 return allDrawn;
Robert Carr13f7be9e2015-12-02 18:39:45 -0800637 }
638
Chong Zhang92147042016-05-09 12:47:11 -0700639 boolean canRestoreSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700640 for (int i = windows.size() -1; i >= 0; i--) {
641 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700642 if (w.canRestoreSurface()) {
Robert Carr13f7be9e2015-12-02 18:39:45 -0800643 return true;
644 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700645 }
646 return false;
647 }
648
Chong Zhang92147042016-05-09 12:47:11 -0700649 void clearVisibleBeforeClientHidden() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700650 for (int i = windows.size() - 1; i >= 0; i--) {
651 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700652 w.clearVisibleBeforeClientHidden();
653 }
654 }
655
Chong Zhang8e4bda92016-05-04 15:08:18 -0700656 /**
657 * Whether the app has some window that is invisible in layout, but
658 * animating with saved surface.
659 */
660 boolean isAnimatingInvisibleWithSavedSurface() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700661 for (int i = windows.size() - 1; i >= 0; i--) {
662 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700663 if (w.isAnimatingInvisibleWithSavedSurface()) {
664 return true;
665 }
666 }
667 return false;
668 }
669
670 /**
671 * Hide all window surfaces that's still invisible in layout but animating
672 * with a saved surface, and mark them destroying.
673 */
674 void stopUsingSavedSurfaceLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700675 for (int i = windows.size() - 1; i >= 0; i--) {
676 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700677 if (w.isAnimatingInvisibleWithSavedSurface()) {
678 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
679 "stopUsingSavedSurfaceLocked: " + w);
680 w.clearAnimatingWithSavedSurface();
681 w.mDestroying = true;
682 w.mWinAnimator.hide("stopUsingSavedSurfaceLocked");
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700683 mService.mWallpaperControllerLocked.hideWallpapers(w);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700684 }
685 }
686 destroySurfaces();
687 }
688
Chong Zhangf58631a2016-05-24 16:02:10 -0700689 void markSavedSurfaceExiting() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700690 for (int i = windows.size() - 1; i >= 0; i--) {
691 final WindowState w = windows.get(i);
Chong Zhangf58631a2016-05-24 16:02:10 -0700692 if (w.isAnimatingInvisibleWithSavedSurface()) {
693 w.mAnimatingExit = true;
694 w.mWinAnimator.mAnimating = true;
695 }
696 }
697 }
698
Chong Zhangbef461f2015-10-27 11:38:24 -0700699 void restoreSavedSurfaces() {
Chong Zhang92147042016-05-09 12:47:11 -0700700 if (!canRestoreSurfaces()) {
701 clearVisibleBeforeClientHidden();
Chong Zhangbef461f2015-10-27 11:38:24 -0700702 return;
703 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800704 // Check if we have enough drawn windows to mark allDrawn= true.
705 int numInteresting = 0;
706 int numDrawn = 0;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700707 for (int i = windows.size() - 1; i >= 0; i--) {
708 WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700709 if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800710 && (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
711 numInteresting++;
Chong Zhang92147042016-05-09 12:47:11 -0700712 if (w.hasSavedSurface()) {
713 w.restoreSavedSurface();
714 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800715 if (w.isDrawnLw()) {
716 numDrawn++;
717 }
718 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700719 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800720
Chong Zhang92147042016-05-09 12:47:11 -0700721 if (!allDrawn) {
722 allDrawn = (numInteresting > 0) && (numInteresting == numDrawn);
723 if (allDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700724 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Chong Zhang92147042016-05-09 12:47:11 -0700725 }
726 }
727 clearVisibleBeforeClientHidden();
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800728
729 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
Wale Ogunwale455fac52016-07-21 07:24:49 -0700730 "restoreSavedSurfaces: " + this + " allDrawn=" + allDrawn
Chong Zhang92147042016-05-09 12:47:11 -0700731 + " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
Chong Zhangbef461f2015-10-27 11:38:24 -0700732 }
733
734 void destroySavedSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700735 for (int i = windows.size() - 1; i >= 0; i--) {
736 WindowState win = windows.get(i);
Robert Carr13f7be9e2015-12-02 18:39:45 -0800737 win.destroySavedSurface();
Chong Zhangbef461f2015-10-27 11:38:24 -0700738 }
Chong Zhang92147042016-05-09 12:47:11 -0700739 }
740
741 void clearAllDrawn() {
742 allDrawn = false;
743 deferClearAllDrawn = false;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700744 allDrawnExcludingSaved = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700745 }
746
Wale Ogunwale98e70d02014-11-10 12:12:27 -0800747 @Override
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700748 void removeWindow(WindowState win) {
749 super.removeWindow(win);
750
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700751 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700752 if (startingWindow == win) {
753 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700754 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700755 } else if (windows.size() == 0 && startingData != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700756 // If this is the last window and we had requested a starting transition window,
757 // well there is no point now.
758 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
759 startingData = null;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700760 } else if (windows.size() == 1 && startingView != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700761 // If this is the last window except for a starting transition window,
762 // we need to get rid of the starting transition.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700763 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700764 }
765 }
766
Chong Zhang112eb8c2015-11-02 11:17:00 -0800767 void removeAllDeadWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700768 for (int winNdx = windows.size() - 1; winNdx >= 0;
769 // WindowState#removeIfPossible() at bottom of loop may remove multiple entries from
770 // windows if the window to be removed has child windows. It also may
771 // not remove any windows from windows at all if win is exiting and
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700772 // currently animating away. This ensures that winNdx is monotonically decreasing
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700773 // and never beyond windows bounds.
774 winNdx = Math.min(winNdx - 1, windows.size() - 1)) {
775 WindowState win = windows.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800776 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700777 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
778 "removeAllDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800779 // Set mDestroying, we don't want any animation or delayed removal here.
780 win.mDestroying = true;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700781 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800782 }
783 }
784 }
785
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700786 boolean hasWindowsAlive() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700787 for (int i = windows.size() - 1; i >= 0; i--) {
788 if (!windows.get(i).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700789 return true;
790 }
791 }
792 return false;
793 }
794
Robert Carra1eb4392015-12-10 12:43:51 -0800795 void setReplacingWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700796 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
797 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800798
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700799 for (int i = windows.size() - 1; i >= 0; i--) {
800 final WindowState w = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800801 w.setReplacing(animate);
802 }
803 if (animate) {
804 // Set-up dummy animation so we can start treating windows associated with this
805 // token like they are in transition before the new app window is ready for us to
806 // run the real transition animation.
807 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
808 "setReplacingWindow() Setting dummy animation on: " + this);
809 mAppAnimator.setDummyAnimation();
810 }
811 }
812
Robert Carr23fa16b2016-01-13 13:19:58 -0800813 void setReplacingChildren() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700814 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800815 + " with replacing child windows.");
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700816 for (int i = windows.size() - 1; i >= 0; i--) {
817 final WindowState w = windows.get(i);
Robert Carrd1a010f2016-04-07 22:36:22 -0700818 if (w.shouldBeReplacedWithChildren()) {
Robert Carr23fa16b2016-01-13 13:19:58 -0800819 w.setReplacing(false /* animate */);
820 }
821 }
822 }
823
Chong Zhangf596cd52016-01-05 13:42:44 -0800824 void resetReplacingWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700825 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
826 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800827
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700828 for (int i = windows.size() - 1; i >= 0; i--) {
829 final WindowState w = windows.get(i);
Chong Zhangf596cd52016-01-05 13:42:44 -0800830 w.resetReplacing();
831 }
832 }
833
Chong Zhang4d7369a2016-04-25 16:09:14 -0700834 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700835 for (int i = windows.size() - 1; i >= 0; i--) {
836 final WindowState w = windows.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -0700837 w.requestUpdateWallpaperIfNeeded();
838 }
839 }
840
Chong Zhangd78ddb42016-03-02 17:01:14 -0800841 boolean isRelaunching() {
842 return mPendingRelaunchCount > 0;
843 }
844
845 void startRelaunching() {
846 if (canFreezeBounds()) {
847 freezeBounds();
848 }
849 mPendingRelaunchCount++;
850 }
851
852 void finishRelaunching() {
853 if (canFreezeBounds()) {
854 unfreezeBounds();
855 }
856 if (mPendingRelaunchCount > 0) {
857 mPendingRelaunchCount--;
858 }
859 }
860
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700861 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700862 if (mPendingRelaunchCount == 0) {
863 return;
864 }
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700865 if (canFreezeBounds()) {
866 unfreezeBounds();
867 }
868 mPendingRelaunchCount = 0;
869 }
870
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700871 @Override
Robert Carra1eb4392015-12-10 12:43:51 -0800872 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700873 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700874
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700875 for (int i = windows.size() - 1; i >= 0; i--) {
876 final WindowState candidate = windows.get(i);
877 if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null
878 && candidate.getWindowTag().toString().equals(w.getWindowTag().toString())) {
879
Robert Carra1eb4392015-12-10 12:43:51 -0800880 candidate.mReplacingWindow = w;
Robert Carrb439a632016-04-07 22:52:10 -0700881 w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow;
Chong Zhangf596cd52016-01-05 13:42:44 -0800882 // if we got a replacement window, reset the timeout to give drawing more time
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700883 mService.scheduleReplacingWindowTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -0800884 }
885 }
Robert Carra1eb4392015-12-10 12:43:51 -0800886 }
887
888 boolean waitingForReplacement() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700889 for (int i = windows.size() - 1; i >= 0; i--) {
890 WindowState candidate = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800891 if (candidate.mWillReplaceWindow) {
892 return true;
893 }
894 }
895 return false;
896 }
897
Chong Zhangf596cd52016-01-05 13:42:44 -0800898 void clearTimedoutReplacesLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700899 for (int i = windows.size() - 1; i >= 0;
900 // WindowState#remove() at bottom of loop may remove multiple entries from windows if
901 // the window to be removed has child windows. It also may not remove any windows from
902 // windows at all if win is exiting and currently animating away. This ensures that
903 // winNdx is monotonically decreasing and never beyond windows bounds.
904 i = Math.min(i - 1, windows.size() - 1)) {
905 final WindowState candidate = windows.get(i);
906 if (!candidate.mWillReplaceWindow) {
Robert Carra1eb4392015-12-10 12:43:51 -0800907 continue;
908 }
909 candidate.mWillReplaceWindow = false;
Robert Carrb439a632016-04-07 22:52:10 -0700910 if (candidate.mReplacingWindow != null) {
911 candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false;
912 }
Chong Zhangf596cd52016-01-05 13:42:44 -0800913 // Since the window already timed out, remove it immediately now.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700914 // Use WindowState#remove() instead of WindowState#removeIfPossible(), as the latter
Chong Zhangf596cd52016-01-05 13:42:44 -0800915 // delays removal on certain conditions, which will leave the stale window in the
916 // stack and marked mWillReplaceWindow=false, so the window will never be removed.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700917 candidate.remove();
Robert Carra1eb4392015-12-10 12:43:51 -0800918 }
919 }
920
Chong Zhangd78ddb42016-03-02 17:01:14 -0800921 private boolean canFreezeBounds() {
922 // For freeform windows, we can't freeze the bounds at the moment because this would make
923 // the resizing unresponsive.
924 return mTask != null && !mTask.inFreeformWorkspace();
925 }
926
Jorim Jaggi0429f352015-12-22 16:29:16 +0100927 /**
928 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
929 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
930 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
931 * with a queue.
932 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800933 private void freezeBounds() {
Jorim Jaggi0429f352015-12-22 16:29:16 +0100934 mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700935
936 if (mTask.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
937 // We didn't call prepareFreezingBounds on the task, so use the current value.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700938 final Configuration config = new Configuration(mService.mCurConfiguration);
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700939 config.updateFrom(mTask.mOverrideConfig);
940 mFrozenMergedConfig.offer(config);
941 } else {
942 mFrozenMergedConfig.offer(new Configuration(mTask.mPreparedFrozenMergedConfig));
943 }
944 mTask.mPreparedFrozenMergedConfig.setToDefaults();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100945 }
946
947 /**
948 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
949 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800950 private void unfreezeBounds() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700951 if (!mFrozenBounds.isEmpty()) {
952 mFrozenBounds.remove();
953 }
954 if (!mFrozenMergedConfig.isEmpty()) {
955 mFrozenMergedConfig.remove();
956 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700957 for (int i = windows.size() - 1; i >= 0; i--) {
958 final WindowState win = windows.get(i);
Jorim Jaggi69abc192016-02-04 19:34:00 -0800959 if (!win.mHasSurface) {
960 continue;
961 }
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100962 win.mLayoutNeeded = true;
963 win.setDisplayLayoutNeeded();
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700964 if (!mService.mResizingWindows.contains(win)) {
965 mService.mResizingWindows.add(win);
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100966 }
967 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700968 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100969 }
970
Robert Carr91b228092016-06-28 17:32:37 -0700971 void addSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
972 mSurfaceViewBackgrounds.add(background);
973 }
974
975 void removeSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
976 mSurfaceViewBackgrounds.remove(background);
977 updateSurfaceViewBackgroundVisibilities();
978 }
979
980 // We use DimLayers behind SurfaceViews to prevent holes while resizing and creating.
981 // However, we need to ensure one SurfaceView doesn't cover another when they are both placed
982 // below the main app window (as traditionally a SurfaceView which is never drawn
983 // to is totally translucent). So we look at all our SurfaceView backgrounds and only enable
984 // the background for the SurfaceView with lowest Z order
985 void updateSurfaceViewBackgroundVisibilities() {
986 WindowSurfaceController.SurfaceControlWithBackground bottom = null;
987 int bottomLayer = Integer.MAX_VALUE;
988 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
989 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
990 if (sc.mVisible && sc.mLayer < bottomLayer) {
991 bottomLayer = sc.mLayer;
992 bottom = sc;
993 }
994 }
995 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
996 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
997 sc.updateBackgroundVisibility(sc != bottom);
998 }
999 }
1000
Jorim Jaggi6626f542016-08-22 13:08:44 -07001001 /**
1002 * See {@link WindowManagerService#overridePlayingAppAnimationsLw}
1003 */
1004 void overridePlayingAppAnimations(Animation a) {
1005 if (mAppAnimator.isAnimating()) {
1006 final WindowState win = findMainWindow();
1007 final int width = win.mContainingFrame.width();
1008 final int height = win.mContainingFrame.height();
1009 mAppAnimator.setAnimation(a, width, height, false, STACK_CLIP_NONE);
1010 }
1011 }
1012
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001013 void resetJustMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001014 for (int i = windows.size() - 1; i >= 0; i--) {
1015 windows.get(i).resetJustMovedInStack();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001016 }
1017 }
1018
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001019 void setWaitingForDrawnIfResizingChanged() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001020 for (int i = windows.size() - 1; i >= 0; --i) {
1021 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001022 if (win.isDragResizeChanged()) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001023 mService.mWaitingForDrawn.add(win);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001024 }
1025 }
1026 }
1027
1028 void resizeWindows() {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001029 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001030 // Some windows won't go through the resizing process, if they don't have a surface, so
1031 // destroy all saved surfaces here.
1032 destroySavedSurfaces();
1033
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001034 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1035 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001036 if (win.mHasSurface && !resizingWindows.contains(win)) {
1037 if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
1038 resizingWindows.add(win);
1039
1040 // If we are not drag resizing, force recreating of a new surface so updating
1041 // the content and positioning that surface will be in sync.
1042 //
1043 // As we use this flag as a hint to freeze surface boundary updates,
1044 // we'd like to only apply this to TYPE_BASE_APPLICATION,
Chong Zhang921f8e32016-08-17 14:26:57 -07001045 // windows of TYPE_APPLICATION (or TYPE_DRAWN_APPLICATION) like dialogs,
1046 // could appear to not be drag resizing while they resize, but we'd
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001047 // still like to manipulate their frame to update crop, etc...
1048 //
1049 // Anyway we don't need to synchronize position and content updates for these
1050 // windows since they aren't at the base layer and could be moved around anyway.
1051 if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
1052 !mTask.mStack.getBoundsAnimating() && !win.isGoneForLayoutLw() &&
1053 !mTask.inPinnedWorkspace()) {
1054 win.setResizedWhileNotDragResizing(true);
1055 }
1056 }
1057 if (win.isGoneForLayoutLw()) {
1058 win.mResizedWhileGone = true;
1059 }
1060 }
1061 }
1062
1063 void moveWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001064 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1065 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001066 if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
1067 win.mMovedByResize = true;
1068 }
1069 }
1070
1071 void notifyMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001072 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1073 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001074 win.notifyMovedInStack();
1075 }
1076 }
1077
1078 void resetDragResizingChangeReported() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001079 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1080 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001081 win.resetDragResizingChangeReported();
1082 }
1083 }
1084
1085 void detachDisplay() {
1086 boolean doAnotherLayoutPass = false;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001087 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001088 // We are in the middle of changing the state of displays/stacks/tasks. We need
1089 // to finish that, before we let layout interfere with it.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001090 windows.get(winNdx).removeIfPossible();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001091 doAnotherLayoutPass = true;
1092 }
1093 if (doAnotherLayoutPass) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001094 mService.mWindowPlacerLocked.requestTraversal();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001095 }
1096 }
1097
1098 void forceWindowsScaleableInTransaction(boolean force) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001099 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1100 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001101 if (winAnimator == null || !winAnimator.hasSurface()) {
1102 continue;
1103 }
1104 winAnimator.mSurfaceController.forceScaleableInTransaction(force);
1105 }
1106 }
1107
1108 boolean isAnimating() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001109 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1110 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001111 if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
1112 return true;
1113 }
1114 }
1115 return false;
1116 }
1117
1118 void setAppLayoutChanges(int changes, String reason, int displayId) {
1119 final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001120 for (int i = windows.size() - 1; i >= 0; i--) {
1121 if (displayId == windows.get(i).getDisplayId()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001122 windowAnimator.setPendingLayoutChanges(displayId, changes);
1123 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001124 mService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001125 reason, windowAnimator.getPendingLayoutChanges(displayId));
1126 }
1127 break;
1128 }
1129 }
1130 }
1131
1132 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001133 for (int i = windows.size() - 1; i >= 0; i--) {
1134 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001135 if (win.mWillReplaceWindow && win.mReplacingWindow == replacement
1136 && replacement.hasDrawnLw()) {
1137 replacement.mSkipEnterAnimationForSeamlessReplacement = false;
1138 win.removeReplacedWindow();
1139 }
1140 }
1141 }
1142
1143 void startFreezingScreen() {
1144 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
1145 + hidden + " freezing=" + mAppAnimator.freezingScreen);
1146 if (!hiddenRequested) {
1147 if (!mAppAnimator.freezingScreen) {
1148 mAppAnimator.freezingScreen = true;
1149 mAppAnimator.lastFreezeDuration = 0;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001150 mService.mAppsFreezingScreen++;
1151 if (mService.mAppsFreezingScreen == 1) {
1152 mService.startFreezingDisplayLocked(false, 0, 0);
1153 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1154 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001155 }
1156 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001157 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001158 for (int i = 0; i < count; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001159 final WindowState w = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001160 w.mAppFreezing = true;
1161 }
1162 }
1163 }
1164
1165 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
1166 if (!mAppAnimator.freezingScreen) {
1167 return;
1168 }
1169 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001170 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001171 boolean unfrozeWindows = false;
1172 for (int i = 0; i < count; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001173 final WindowState w = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001174 if (w.mAppFreezing) {
1175 w.mAppFreezing = false;
1176 if (w.mHasSurface && !w.mOrientationChanging
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001177 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001178 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
1179 w.mOrientationChanging = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001180 mService.mWindowPlacerLocked.mOrientationChangeComplete = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001181 }
1182 w.mLastFreezeDuration = 0;
1183 unfrozeWindows = true;
1184 w.setDisplayLayoutNeeded();
1185 }
1186 }
1187 if (force || unfrozeWindows) {
1188 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
1189 mAppAnimator.freezingScreen = false;
1190 mAppAnimator.lastFreezeDuration =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001191 (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime);
1192 mService.mAppsFreezingScreen--;
1193 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001194 }
1195 if (unfreezeSurfaceNow) {
1196 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001197 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001198 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001199 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001200 }
1201 }
1202
1203 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001204 final AppWindowToken fromToken = mService.findAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001205 if (fromToken == null) {
1206 return false;
1207 }
1208
1209 final WindowState tStartingWindow = fromToken.startingWindow;
1210 if (tStartingWindow != null && fromToken.startingView != null) {
1211 // In this case, the starting icon has already been displayed, so start
1212 // letting windows get shown immediately without any more transitions.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001213 mService.mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001214
1215 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1216 + " from " + fromToken + " to " + this);
1217
1218 final long origId = Binder.clearCallingIdentity();
1219
1220 // Transfer the starting window over to the new token.
1221 startingData = fromToken.startingData;
1222 startingView = fromToken.startingView;
1223 startingDisplayed = fromToken.startingDisplayed;
1224 fromToken.startingDisplayed = false;
1225 startingWindow = tStartingWindow;
1226 reportedVisible = fromToken.reportedVisible;
1227 fromToken.startingData = null;
1228 fromToken.startingView = null;
1229 fromToken.startingWindow = null;
1230 fromToken.startingMoved = true;
1231 tStartingWindow.mToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001232 tStartingWindow.mAppToken = this;
1233
1234 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1235 "Removing starting window: " + tStartingWindow);
1236 tStartingWindow.getWindowList().remove(tStartingWindow);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001237 mService.mWindowsChanged = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001238 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1239 "Removing starting " + tStartingWindow + " from " + fromToken);
1240 fromToken.removeWindow(tStartingWindow);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001241 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001242
1243 // Propagate other interesting state between the tokens. If the old token is displayed,
1244 // we should immediately force the new one to be displayed. If it is animating, we need
1245 // to move that animation to the new one.
1246 if (fromToken.allDrawn) {
1247 allDrawn = true;
1248 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1249 }
1250 if (fromToken.firstWindowDrawn) {
1251 firstWindowDrawn = true;
1252 }
1253 if (!fromToken.hidden) {
1254 hidden = false;
1255 hiddenRequested = false;
1256 }
1257 if (clientHidden != fromToken.clientHidden) {
1258 clientHidden = fromToken.clientHidden;
1259 sendAppVisibilityToClients();
1260 }
1261 fromToken.mAppAnimator.transferCurrentAnimation(
1262 mAppAnimator, tStartingWindow.mWinAnimator);
1263
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001264 mService.updateFocusedWindowLocked(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001265 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001266 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1267 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001268 Binder.restoreCallingIdentity(origId);
1269 return true;
1270 } else if (fromToken.startingData != null) {
1271 // The previous app was getting ready to show a
1272 // starting window, but hasn't yet done so. Steal it!
1273 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1274 "Moving pending starting from " + fromToken + " to " + this);
1275 startingData = fromToken.startingData;
1276 fromToken.startingData = null;
1277 fromToken.startingMoved = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001278 final Message m = mService.mH.obtainMessage(H.ADD_STARTING, this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001279 // Note: we really want to do sendMessageAtFrontOfQueue() because we want to process the
1280 // message ASAP, before any other queued messages.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001281 mService.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001282 return true;
1283 }
1284
1285 final AppWindowAnimator tAppAnimator = fromToken.mAppAnimator;
1286 final AppWindowAnimator wAppAnimator = mAppAnimator;
1287 if (tAppAnimator.thumbnail != null) {
1288 // The old token is animating with a thumbnail, transfer that to the new token.
1289 if (wAppAnimator.thumbnail != null) {
1290 wAppAnimator.thumbnail.destroy();
1291 }
1292 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
1293 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
1294 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
1295 tAppAnimator.thumbnail = null;
1296 }
1297 return false;
1298 }
1299
1300 int getWindowsCount() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001301 return windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001302 }
1303
1304 void setAllAppWinAnimators() {
1305 final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
1306 allAppWinAnimators.clear();
1307
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001308 final int windowsCount = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001309 for (int j = 0; j < windowsCount; j++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001310 allAppWinAnimators.add(windows.get(j).mWinAnimator);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001311 }
1312 }
1313
Craig Mautnerdbb79912012-03-01 18:59:14 -08001314 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001315 AppWindowToken asAppWindowToken() {
1316 // I am an app window token!
1317 return this;
1318 }
1319
1320 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001321 void dump(PrintWriter pw, String prefix) {
1322 super.dump(pw, prefix);
1323 if (appToken != null) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001324 pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001325 }
Craig Mautner83162a92015-01-26 14:43:30 -08001326 pw.print(prefix); pw.print("task="); pw.println(mTask);
1327 pw.print(prefix); pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001328 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
1329 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
1330 pw.print(" clientHidden="); pw.print(clientHidden);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07001331 pw.print(" reportedDrawn="); pw.print(reportedDrawn);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001332 pw.print(" reportedVisible="); pw.println(reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07001333 if (paused) {
1334 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001335 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001336 if (mAppStopped) {
1337 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
1338 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001339 if (numInterestingWindows != 0 || numDrawnWindows != 0
Craig Mautner6fbda632012-07-03 09:26:39 -07001340 || allDrawn || mAppAnimator.allDrawn) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001341 pw.print(prefix); pw.print("numInterestingWindows=");
1342 pw.print(numInterestingWindows);
1343 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
1344 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07001345 pw.print(" allDrawn="); pw.print(allDrawn);
1346 pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
1347 pw.println(")");
1348 }
1349 if (inPendingTransaction) {
1350 pw.print(prefix); pw.print("inPendingTransaction=");
1351 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001352 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08001353 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001354 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
1355 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08001356 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08001357 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001358 }
1359 if (startingWindow != null || startingView != null
1360 || startingDisplayed || startingMoved) {
1361 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
1362 pw.print(" startingView="); pw.print(startingView);
1363 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001364 pw.print(" startingMoved="); pw.println(startingMoved);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001365 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01001366 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001367 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001368 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08001369 }
1370 if (mPendingRelaunchCount != 0) {
1371 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01001372 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001373 }
1374
1375 @Override
1376 public String toString() {
1377 if (stringName == null) {
1378 StringBuilder sb = new StringBuilder();
1379 sb.append("AppWindowToken{");
1380 sb.append(Integer.toHexString(System.identityHashCode(this)));
1381 sb.append(" token="); sb.append(token); sb.append('}');
1382 stringName = sb.toString();
1383 }
1384 return stringName;
1385 }
Jeff Browne9bdb312012-04-05 15:30:10 -07001386}