blob: 4b1cde7e0a8f2080f6ad6a6ac92e325ae23c4392 [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;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070038import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
39import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
40import static com.android.server.wm.WindowManagerService.logWithStack;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080041
Jeff Brown4532e612012-04-05 14:27:12 -070042import com.android.server.input.InputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080043import com.android.server.wm.WindowManagerService.H;
44
Filip Gruszczynskia590c992015-11-25 16:45:26 -080045import android.annotation.NonNull;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080046import android.content.pm.ActivityInfo;
Jorim Jaggi26c8c422016-05-09 19:57:25 -070047import android.content.res.Configuration;
Jorim Jaggi0429f352015-12-22 16:29:16 +010048import android.graphics.Rect;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070049import android.os.Binder;
50import android.os.IBinder;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080051import android.os.Message;
52import android.os.RemoteException;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070053import android.os.SystemClock;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080054import android.util.Slog;
55import android.view.IApplicationToken;
56import android.view.View;
57import android.view.WindowManager;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080058
59import java.io.PrintWriter;
Jorim Jaggi0429f352015-12-22 16:29:16 +010060import java.util.ArrayDeque;
Craig Mautnerb1fd65c02013-02-05 13:34:57 -080061import java.util.ArrayList;
62
63class AppTokenList extends ArrayList<AppWindowToken> {
64}
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080065
66/**
67 * Version of WindowToken that is specifically for a particular application (or
68 * really activity) that is displaying windows.
69 */
Craig Mautnere32c3072012-03-12 15:25:35 -070070class AppWindowToken extends WindowToken {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080071 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
72
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080073 // Non-null only for application tokens.
74 final IApplicationToken appToken;
75
Filip Gruszczynskia590c992015-11-25 16:45:26 -080076 @NonNull final AppWindowAnimator mAppAnimator;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070077
Dianne Hackborne30e02f2014-05-27 18:24:45 -070078 final boolean voiceInteraction;
79
Craig Mautner83162a92015-01-26 14:43:30 -080080 Task mTask;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080081 boolean appFullscreen;
82 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Craig Mautner4c5eb222013-11-18 12:59:05 -080083 boolean layoutConfigChanges;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -070084 boolean showForAllUsers;
Yorke Lee0e852472016-06-15 10:03:18 -070085 int targetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -070086
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080087 // The input dispatching timeout for this application token in nanoseconds.
88 long inputDispatchingTimeoutNanos;
89
90 // These are used for determining when all windows associated with
91 // an activity have been drawn, so they can be made visible together
92 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -070093 // initialize so that it doesn't match mTransactionSequence which is an int.
94 long lastTransactionSequence = Long.MIN_VALUE;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080095 int numInterestingWindows;
96 int numDrawnWindows;
97 boolean inPendingTransaction;
98 boolean allDrawn;
Craig Mautner7636dfb2012-11-16 15:24:11 -080099 // Set to true when this app creates a surface while in the middle of an animation. In that
100 // case do not clear allDrawn until the animation completes.
101 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800102
Chong Zhang8e4bda92016-05-04 15:08:18 -0700103 // These are to track the app's real drawing status if there were no saved surfaces.
104 boolean allDrawnExcludingSaved;
105 int numInterestingWindowsExcludingSaved;
106 int numDrawnWindowsExclusingSaved;
107
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800108 // Is this window's surface needed? This is almost like hidden, except
109 // it will sometimes be true a little earlier: when the token has
110 // been shown, but is still waiting for its app transition to execute
111 // before making its windows shown.
112 boolean hiddenRequested;
113
114 // Have we told the window clients to hide themselves?
115 boolean clientHidden;
116
117 // Last visibility state we reported to the app token.
118 boolean reportedVisible;
119
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700120 // Last drawn state we reported to the app token.
121 boolean reportedDrawn;
122
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800123 // Set to true when the token has been removed from the window mgr.
124 boolean removed;
125
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800126 // Information about an application starting window if displayed.
127 StartingData startingData;
128 WindowState startingWindow;
129 View startingView;
130 boolean startingDisplayed;
131 boolean startingMoved;
132 boolean firstWindowDrawn;
133
134 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700135 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800136
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 Ogunwale2049dbf2016-08-02 21:05:23 -0700154 AppWindowToken(WindowManagerService service, IApplicationToken _token, boolean _voiceInteraction) {
155 super(service, _token.asBinder(), WindowManager.LayoutParams.TYPE_APPLICATION, true);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800156 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
162 void sendAppVisibilityToClients() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700163 final int N = windows.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800164 for (int i=0; i<N; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700165 WindowState win = windows.get(i);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800166 if (win == startingWindow && clientHidden) {
167 // Don't hide the starting window.
168 continue;
169 }
170 try {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800171 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800172 "Setting visibility of " + win + ": " + (!clientHidden));
173 win.mClient.dispatchAppVisibility(!clientHidden);
174 } catch (RemoteException e) {
175 }
176 }
177 }
178
Chong Zhang92147042016-05-09 12:47:11 -0700179 void setVisibleBeforeClientHidden() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700180 for (int i = windows.size() - 1; i >= 0; i--) {
181 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700182 w.setVisibleBeforeClientHidden();
183 }
184 }
185
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800186 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
187 firstWindowDrawn = true;
188
189 // We now have a good window to show, remove dead placeholders
190 removeAllDeadWindows();
191
192 if (startingData != null) {
193 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
194 + win.mToken + ": first real window is shown, no animation");
195 // If this initial window is animating, stop it -- we will do an animation to reveal
196 // it from behind the starting window, so there is no need for it to also be doing its
197 // own stuff.
198 winAnimator.clearAnimation();
199 winAnimator.mService.mFinishedStarting.add(this);
200 winAnimator.mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
201 }
202 updateReportedVisibilityLocked();
203 }
204
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800205 void updateReportedVisibilityLocked() {
206 if (appToken == null) {
207 return;
208 }
209
210 int numInteresting = 0;
211 int numVisible = 0;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700212 int numDrawn = 0;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800213 boolean nowGone = true;
214
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800215 if (DEBUG_VISIBILITY) Slog.v(TAG,
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700216 "Update reported visibility: " + this);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700217 final int N = windows.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800218 for (int i=0; i<N; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700219 WindowState win = windows.get(i);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800220 if (win == startingWindow || win.mAppFreezing
221 || win.mViewVisibility != View.VISIBLE
222 || win.mAttrs.type == TYPE_APPLICATION_STARTING
223 || win.mDestroying) {
224 continue;
225 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800226 if (DEBUG_VISIBILITY) {
227 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800228 + win.isDrawnLw()
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700229 + ", isAnimationSet=" + win.mWinAnimator.isAnimationSet());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800230 if (!win.isDrawnLw()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800231 Slog.v(TAG, "Not displayed: s=" +
Robert Carre6a83512015-11-03 16:09:21 -0800232 win.mWinAnimator.mSurfaceController
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800233 + " pv=" + win.mPolicyVisibility
Craig Mautner749a7bb2012-04-02 13:49:53 -0700234 + " mDrawState=" + win.mWinAnimator.mDrawState
Wale Ogunwale9d147902016-07-16 11:58:55 -0700235 + " ph=" + win.isParentWindowHidden()
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800236 + " th="
237 + (win.mAppToken != null
238 ? win.mAppToken.hiddenRequested : false)
Craig Mautnera2c77052012-03-26 12:14:43 -0700239 + " a=" + win.mWinAnimator.mAnimating);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800240 }
241 }
242 numInteresting++;
243 if (win.isDrawnLw()) {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700244 numDrawn++;
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700245 if (!win.mWinAnimator.isAnimationSet()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800246 numVisible++;
247 }
248 nowGone = false;
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700249 } else if (win.mWinAnimator.isAnimationSet()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800250 nowGone = false;
251 }
252 }
253
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700254 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800255 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700256 if (!nowGone) {
257 // If the app is not yet gone, then it can only become visible/drawn.
258 if (!nowDrawn) {
259 nowDrawn = reportedDrawn;
260 }
261 if (!nowVisible) {
262 nowVisible = reportedVisible;
263 }
264 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800265 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800266 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700267 if (nowDrawn != reportedDrawn) {
268 if (nowDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700269 Message m = mService.mH.obtainMessage(
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700270 H.REPORT_APPLICATION_TOKEN_DRAWN, this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700271 mService.mH.sendMessage(m);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700272 }
273 reportedDrawn = nowDrawn;
274 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800275 if (nowVisible != reportedVisible) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800276 if (DEBUG_VISIBILITY) Slog.v(
277 TAG, "Visibility changed in " + this
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800278 + ": vis=" + nowVisible);
279 reportedVisible = nowVisible;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700280 Message m = mService.mH.obtainMessage(
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800281 H.REPORT_APPLICATION_TOKEN_WINDOWS,
282 nowVisible ? 1 : 0,
283 nowGone ? 1 : 0,
284 this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700285 mService.mH.sendMessage(m);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800286 }
287 }
288
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700289 boolean setVisibility(WindowManager.LayoutParams lp,
290 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
291
292 boolean delayed = false;
293 inPendingTransaction = false;
294
295 if (clientHidden == visible) {
296 clientHidden = !visible;
297 sendAppVisibilityToClients();
298 }
299
300 // Allow for state changes and animation to be applied if:
301 // * token is transitioning visibility state
302 // * or the token was marked as hidden and is exiting before we had a chance to play the
303 // transition animation
304 // * or this is an opening app and windows are being replaced.
305 boolean visibilityChanged = false;
306 if (hidden == visible || (hidden && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700307 final AccessibilityController accessibilityController = mService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700308 boolean changed = false;
309 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
310 "Changing app " + this + " hidden=" + hidden + " performLayout=" + performLayout);
311
312 boolean runningAppAnimation = false;
313
314 if (transit != AppTransition.TRANSIT_UNSET) {
315 if (mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
316 mAppAnimator.setNullAnimation();
317 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700318 if (mService.applyAnimationLocked(this, lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700319 delayed = runningAppAnimation = true;
320 }
321 final WindowState window = findMainWindow();
322 //TODO (multidisplay): Magnification is supported only for the default display.
323 if (window != null && accessibilityController != null
324 && window.getDisplayId() == DEFAULT_DISPLAY) {
325 accessibilityController.onAppWindowTransitionLocked(window, transit);
326 }
327 changed = true;
328 }
329
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700330 final int windowsCount = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700331 for (int i = 0; i < windowsCount; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700332 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700333 if (win == startingWindow) {
334 // Starting window that's exiting will be removed when the animation finishes.
335 // Mark all relevant flags for that onExitAnimationDone will proceed all the way
336 // to actually remove it.
337 if (!visible && win.isVisibleNow() && mAppAnimator.isAnimating()) {
338 win.mAnimatingExit = true;
339 win.mRemoveOnExit = true;
340 win.mWindowRemovalAllowed = true;
341 }
342 continue;
343 }
344
345 //Slog.i(TAG_WM, "Window " + win + ": vis=" + win.isVisible());
346 //win.dump(" ");
347 if (visible) {
348 if (!win.isVisibleNow()) {
349 if (!runningAppAnimation) {
350 win.mWinAnimator.applyAnimationLocked(TRANSIT_ENTER, true);
351 //TODO (multidisplay): Magnification is supported only for the default
352 if (accessibilityController != null
353 && win.getDisplayId() == DEFAULT_DISPLAY) {
354 accessibilityController.onWindowTransitionLocked(win, TRANSIT_ENTER);
355 }
356 }
357 changed = true;
358 win.setDisplayLayoutNeeded();
359 }
360 } else if (win.isVisibleNow()) {
361 if (!runningAppAnimation) {
362 win.mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false);
363 //TODO (multidisplay): Magnification is supported only for the default
364 if (accessibilityController != null
365 && win.getDisplayId() == DEFAULT_DISPLAY) {
366 accessibilityController.onWindowTransitionLocked(win,TRANSIT_EXIT);
367 }
368 }
369 changed = true;
370 win.setDisplayLayoutNeeded();
371 }
372 }
373
374 hidden = hiddenRequested = !visible;
375 visibilityChanged = true;
376 if (!visible) {
377 stopFreezingScreen(true, true);
378 } else {
379 // If we are being set visible, and the starting window is
380 // not yet displayed, then make sure it doesn't get displayed.
381 WindowState swin = startingWindow;
382 if (swin != null && !swin.isDrawnLw()) {
383 swin.mPolicyVisibility = false;
384 swin.mPolicyVisibilityAfterAnim = false;
385 }
386 }
387
388 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setVisibility: " + this
389 + ": hidden=" + hidden + " hiddenRequested=" + hiddenRequested);
390
391 if (changed) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700392 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700393 if (performLayout) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700394 mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700395 false /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700396 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700397 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700398 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700399 }
400 }
401
402 if (mAppAnimator.animation != null) {
403 delayed = true;
404 }
405
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700406 for (int i = windows.size() - 1; i >= 0 && !delayed; i--) {
407 if (windows.get(i).mWinAnimator.isWindowAnimationSet()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700408 delayed = true;
409 }
410 }
411
412 if (visibilityChanged) {
413 if (visible && !delayed) {
414 // The token was made immediately visible, there will be no entrance animation.
415 // We need to inform the client the enter animation was finished.
416 mEnteringAnimation = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700417 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700418 }
419
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700420 if (!mService.mClosingApps.contains(this) && !mService.mOpeningApps.contains(this)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700421 // The token is not closing nor opening, so even if there is an animation set, that
422 // doesn't mean that it goes through the normal app transition cycle so we have
423 // to inform the docked controller about visibility change.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700424 mService.getDefaultDisplayContentLocked().getDockedDividerController()
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700425 .notifyAppVisibilityChanged();
426 }
427 }
428
429 return delayed;
430 }
431
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800432 WindowState findMainWindow() {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700433 WindowState candidate = null;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700434 int j = windows.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800435 while (j > 0) {
436 j--;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700437 WindowState win = windows.get(j);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800438 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
439 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700440 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900441 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700442 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800443 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700444 candidate = win;
445 } else {
446 return win;
447 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800448 }
449 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700450 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800451 }
452
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800453 boolean windowsAreFocusable() {
454 return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800455 }
456
Craig Mautner72669d12012-12-18 17:23:54 -0800457 boolean isVisible() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700458 final int N = windows.size();
Craig Mautner72669d12012-12-18 17:23:54 -0800459 for (int i=0; i<N; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700460 WindowState win = windows.get(i);
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700461 // If we're animating with a saved surface, we're already visible.
462 // Return true so that the alpha doesn't get cleared.
Craig Mautner72669d12012-12-18 17:23:54 -0800463 if (!win.mAppFreezing
Chong Zhang92147042016-05-09 12:47:11 -0700464 && (win.mViewVisibility == View.VISIBLE || win.isAnimatingWithSavedSurface()
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700465 || (win.mWinAnimator.isAnimationSet()
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700466 && !mService.mAppTransition.isTransitionSet()))
Filip Gruszczynski57f76f12015-11-04 16:10:54 -0800467 && !win.mDestroying
468 && win.isDrawnLw()) {
Craig Mautner72669d12012-12-18 17:23:54 -0800469 return true;
470 }
471 }
472 return false;
473 }
474
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700475 boolean isVisibleForUser() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700476 for (int j = windows.size() - 1; j >= 0; j--) {
477 final WindowState w = windows.get(j);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700478 if (!w.isHiddenFromUserLocked()) {
479 return true;
480 }
481 }
482 return false;
483 }
484
Craig Mautnere3119b72015-01-20 15:02:36 -0800485 void removeAppFromTaskLocked() {
486 mIsExiting = false;
487 removeAllWindows();
488
Craig Mautner83162a92015-01-26 14:43:30 -0800489 // Use local variable because removeAppToken will null out mTask.
490 final Task task = mTask;
Craig Mautnere3119b72015-01-20 15:02:36 -0800491 if (task != null) {
492 if (!task.removeAppToken(this)) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800493 Slog.e(TAG, "removeAppFromTaskLocked: token=" + this
Craig Mautnere3119b72015-01-20 15:02:36 -0800494 + " not found.");
495 }
496 task.mStack.mExitingAppTokens.remove(this);
497 }
498 }
499
Chong Zhange05bcb12016-07-26 17:47:29 -0700500 void clearAnimatingFlags() {
Chong Zhangb0d26702016-08-12 16:03:29 -0700501 boolean wallpaperMightChange = false;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700502 for (int i = windows.size() - 1; i >= 0; i--) {
503 final WindowState win = windows.get(i);
Chong Zhange05bcb12016-07-26 17:47:29 -0700504 // We don't want to clear it out for windows that get replaced, because the
505 // animation depends on the flag to remove the replaced window.
506 //
507 // We also don't clear the mAnimatingExit flag for windows which have the
508 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
509 // by the client. We should let animation proceed and not clear this flag or
510 // they won't eventually be removed by WindowStateAnimator#finishExit.
511 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Chong Zhange05bcb12016-07-26 17:47:29 -0700512 // Clear mAnimating flag together with mAnimatingExit. When animation
513 // changes from exiting to entering, we need to clear this flag until the
514 // new animation gets applied, so that isAnimationStarting() becomes true
515 // until then.
516 // Otherwise applySurfaceChangesTransaction will faill to skip surface
517 // placement for this window during this period, one or more frame will
518 // show up with wrong position or scale.
Chong Zhangb0d26702016-08-12 16:03:29 -0700519 if (win.mAnimatingExit) {
520 win.mAnimatingExit = false;
521 wallpaperMightChange = true;
522 }
523 if (win.mWinAnimator.mAnimating) {
524 win.mWinAnimator.mAnimating = false;
525 wallpaperMightChange = true;
526 }
Wale Ogunwale3c0d44e2016-08-11 09:34:45 -0700527 if (win.mDestroying) {
528 win.mDestroying = false;
Chong Zhang12d266f2016-08-11 16:27:43 -0700529 mService.mDestroySurface.remove(win);
Chong Zhangb0d26702016-08-12 16:03:29 -0700530 wallpaperMightChange = true;
Wale Ogunwale3c0d44e2016-08-11 09:34:45 -0700531 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700532 }
533 }
Chong Zhangb0d26702016-08-12 16:03:29 -0700534 if (wallpaperMightChange) {
535 requestUpdateWallpaperIfNeeded();
536 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700537 }
538
Robert Carre12aece2016-02-02 22:43:27 -0800539 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700540 destroySurfaces(false /*cleanupOnResume*/);
541 }
542
543 /**
544 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
545 * the client has finished with them.
546 *
547 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
548 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
549 * others so that they are ready to be reused. If set to false (common case), destroy all
550 * surfaces that's eligible, if the app is already stopped.
551 */
552
553 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700554 final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) windows.clone();
Robert Carre12aece2016-02-02 22:43:27 -0800555 final DisplayContentList displayList = new DisplayContentList();
556 for (int i = allWindows.size() - 1; i >= 0; i--) {
557 final WindowState win = allWindows.get(i);
Chong Zhangeb665572016-05-09 18:28:27 -0700558
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700559 if (!(mAppStopped || win.mWindowRemovalAllowed || cleanupOnResume)) {
Robert Carre12aece2016-02-02 22:43:27 -0800560 continue;
561 }
562
Chong Zhangeb665572016-05-09 18:28:27 -0700563 win.mWinAnimator.destroyPreservedSurfaceLocked();
564
565 if (!win.mDestroying) {
Chong Zhang5471e902016-02-12 15:34:10 -0800566 continue;
Robert Carre12aece2016-02-02 22:43:27 -0800567 }
568
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800569 if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + win
570 + " destroySurfaces: mAppStopped=" + mAppStopped
571 + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed
572 + " win.mRemoveOnExit=" + win.mRemoveOnExit);
573
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700574 if (!cleanupOnResume || win.mRemoveOnExit) {
575 win.destroyOrSaveSurface();
576 }
Robert Carre12aece2016-02-02 22:43:27 -0800577 if (win.mRemoveOnExit) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700578 win.remove();
Robert Carre12aece2016-02-02 22:43:27 -0800579 }
580 final DisplayContent displayContent = win.getDisplayContent();
581 if (displayContent != null && !displayList.contains(displayContent)) {
582 displayList.add(displayContent);
583 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700584 if (cleanupOnResume) {
585 win.requestUpdateWallpaperIfNeeded();
586 }
Robert Carre12aece2016-02-02 22:43:27 -0800587 win.mDestroying = false;
588 }
589 for (int i = 0; i < displayList.size(); i++) {
590 final DisplayContent displayContent = displayList.get(i);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700591 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Robert Carre12aece2016-02-02 22:43:27 -0800592 displayContent.layoutNeeded = true;
593 }
594 }
595
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800596 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700597 * Notify that the app is now resumed, and it was not stopped before, perform a clean
598 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800599 */
Chong Zhangad24f962016-08-25 12:12:33 -0700600 void notifyAppResumed(boolean wasStopped, boolean allowSavedSurface) {
601 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
602 + " allowSavedSurface=" + allowSavedSurface + " " + this);
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700603 mAppStopped = false;
604 if (!wasStopped) {
605 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800606 }
Chong Zhangad24f962016-08-25 12:12:33 -0700607 if (!allowSavedSurface) {
608 destroySavedSurfaces();
609 }
Robert Carre12aece2016-02-02 22:43:27 -0800610 }
611
Chong Zhangbef461f2015-10-27 11:38:24 -0700612 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700613 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
614 * keeping alive in case they were still being used.
615 */
616 void notifyAppStopped() {
617 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
618 mAppStopped = true;
619 destroySurfaces();
620 // Remove any starting window that was added for this app if they are still around.
621 mTask.mService.scheduleRemoveStartingWindowLocked(this);
622 }
623
624 /**
Chong Zhangbef461f2015-10-27 11:38:24 -0700625 * Checks whether we should save surfaces for this app.
626 *
627 * @return true if the surfaces should be saved, false otherwise.
628 */
629 boolean shouldSaveSurface() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800630 // We want to save surface if the app's windows are "allDrawn".
631 // (If we started entering animation early with saved surfaces, allDrawn
632 // should have been restored to true. So we'll save again in that case
633 // even if app didn't actually finish drawing.)
634 return allDrawn;
Robert Carr13f7be9e2015-12-02 18:39:45 -0800635 }
636
Chong Zhang92147042016-05-09 12:47:11 -0700637 boolean canRestoreSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700638 for (int i = windows.size() -1; i >= 0; i--) {
639 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700640 if (w.canRestoreSurface()) {
Robert Carr13f7be9e2015-12-02 18:39:45 -0800641 return true;
642 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700643 }
644 return false;
645 }
646
Chong Zhang92147042016-05-09 12:47:11 -0700647 void clearVisibleBeforeClientHidden() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700648 for (int i = windows.size() - 1; i >= 0; i--) {
649 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700650 w.clearVisibleBeforeClientHidden();
651 }
652 }
653
Chong Zhang8e4bda92016-05-04 15:08:18 -0700654 /**
655 * Whether the app has some window that is invisible in layout, but
656 * animating with saved surface.
657 */
658 boolean isAnimatingInvisibleWithSavedSurface() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700659 for (int i = windows.size() - 1; i >= 0; i--) {
660 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700661 if (w.isAnimatingInvisibleWithSavedSurface()) {
662 return true;
663 }
664 }
665 return false;
666 }
667
668 /**
669 * Hide all window surfaces that's still invisible in layout but animating
670 * with a saved surface, and mark them destroying.
671 */
672 void stopUsingSavedSurfaceLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700673 for (int i = windows.size() - 1; i >= 0; i--) {
674 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700675 if (w.isAnimatingInvisibleWithSavedSurface()) {
676 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
677 "stopUsingSavedSurfaceLocked: " + w);
678 w.clearAnimatingWithSavedSurface();
679 w.mDestroying = true;
680 w.mWinAnimator.hide("stopUsingSavedSurfaceLocked");
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700681 mService.mWallpaperControllerLocked.hideWallpapers(w);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700682 }
683 }
684 destroySurfaces();
685 }
686
Chong Zhangf58631a2016-05-24 16:02:10 -0700687 void markSavedSurfaceExiting() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700688 for (int i = windows.size() - 1; i >= 0; i--) {
689 final WindowState w = windows.get(i);
Chong Zhangf58631a2016-05-24 16:02:10 -0700690 if (w.isAnimatingInvisibleWithSavedSurface()) {
691 w.mAnimatingExit = true;
692 w.mWinAnimator.mAnimating = true;
693 }
694 }
695 }
696
Chong Zhangbef461f2015-10-27 11:38:24 -0700697 void restoreSavedSurfaces() {
Chong Zhang92147042016-05-09 12:47:11 -0700698 if (!canRestoreSurfaces()) {
699 clearVisibleBeforeClientHidden();
Chong Zhangbef461f2015-10-27 11:38:24 -0700700 return;
701 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800702 // Check if we have enough drawn windows to mark allDrawn= true.
703 int numInteresting = 0;
704 int numDrawn = 0;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700705 for (int i = windows.size() - 1; i >= 0; i--) {
706 WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700707 if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800708 && (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
709 numInteresting++;
Chong Zhang92147042016-05-09 12:47:11 -0700710 if (w.hasSavedSurface()) {
711 w.restoreSavedSurface();
712 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800713 if (w.isDrawnLw()) {
714 numDrawn++;
715 }
716 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700717 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800718
Chong Zhang92147042016-05-09 12:47:11 -0700719 if (!allDrawn) {
720 allDrawn = (numInteresting > 0) && (numInteresting == numDrawn);
721 if (allDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700722 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Chong Zhang92147042016-05-09 12:47:11 -0700723 }
724 }
725 clearVisibleBeforeClientHidden();
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800726
727 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
Wale Ogunwale455fac52016-07-21 07:24:49 -0700728 "restoreSavedSurfaces: " + this + " allDrawn=" + allDrawn
Chong Zhang92147042016-05-09 12:47:11 -0700729 + " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
Chong Zhangbef461f2015-10-27 11:38:24 -0700730 }
731
732 void destroySavedSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700733 for (int i = windows.size() - 1; i >= 0; i--) {
734 WindowState win = windows.get(i);
Robert Carr13f7be9e2015-12-02 18:39:45 -0800735 win.destroySavedSurface();
Chong Zhangbef461f2015-10-27 11:38:24 -0700736 }
Chong Zhang92147042016-05-09 12:47:11 -0700737 }
738
739 void clearAllDrawn() {
740 allDrawn = false;
741 deferClearAllDrawn = false;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700742 allDrawnExcludingSaved = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700743 }
744
Wale Ogunwale98e70d02014-11-10 12:12:27 -0800745 @Override
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700746 void removeWindow(WindowState win) {
747 super.removeWindow(win);
748
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700749 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700750 if (startingWindow == win) {
751 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700752 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700753 } else if (windows.size() == 0 && startingData != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700754 // If this is the last window and we had requested a starting transition window,
755 // well there is no point now.
756 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
757 startingData = null;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700758 } else if (windows.size() == 1 && startingView != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700759 // If this is the last window except for a starting transition window,
760 // we need to get rid of the starting transition.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700761 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700762 }
763 }
764
Chong Zhang112eb8c2015-11-02 11:17:00 -0800765 void removeAllDeadWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700766 for (int winNdx = windows.size() - 1; winNdx >= 0;
767 // WindowState#removeIfPossible() at bottom of loop may remove multiple entries from
768 // windows if the window to be removed has child windows. It also may
769 // not remove any windows from windows at all if win is exiting and
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700770 // currently animating away. This ensures that winNdx is monotonically decreasing
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700771 // and never beyond windows bounds.
772 winNdx = Math.min(winNdx - 1, windows.size() - 1)) {
773 WindowState win = windows.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800774 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700775 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
776 "removeAllDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800777 // Set mDestroying, we don't want any animation or delayed removal here.
778 win.mDestroying = true;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700779 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800780 }
781 }
782 }
783
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700784 boolean hasWindowsAlive() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700785 for (int i = windows.size() - 1; i >= 0; i--) {
786 if (!windows.get(i).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700787 return true;
788 }
789 }
790 return false;
791 }
792
Robert Carra1eb4392015-12-10 12:43:51 -0800793 void setReplacingWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700794 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
795 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800796
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700797 for (int i = windows.size() - 1; i >= 0; i--) {
798 final WindowState w = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800799 w.setReplacing(animate);
800 }
801 if (animate) {
802 // Set-up dummy animation so we can start treating windows associated with this
803 // token like they are in transition before the new app window is ready for us to
804 // run the real transition animation.
805 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
806 "setReplacingWindow() Setting dummy animation on: " + this);
807 mAppAnimator.setDummyAnimation();
808 }
809 }
810
Robert Carr23fa16b2016-01-13 13:19:58 -0800811 void setReplacingChildren() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700812 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800813 + " with replacing child windows.");
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700814 for (int i = windows.size() - 1; i >= 0; i--) {
815 final WindowState w = windows.get(i);
Robert Carrd1a010f2016-04-07 22:36:22 -0700816 if (w.shouldBeReplacedWithChildren()) {
Robert Carr23fa16b2016-01-13 13:19:58 -0800817 w.setReplacing(false /* animate */);
818 }
819 }
820 }
821
Chong Zhangf596cd52016-01-05 13:42:44 -0800822 void resetReplacingWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700823 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
824 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800825
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700826 for (int i = windows.size() - 1; i >= 0; i--) {
827 final WindowState w = windows.get(i);
Chong Zhangf596cd52016-01-05 13:42:44 -0800828 w.resetReplacing();
829 }
830 }
831
Chong Zhang4d7369a2016-04-25 16:09:14 -0700832 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700833 for (int i = windows.size() - 1; i >= 0; i--) {
834 final WindowState w = windows.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -0700835 w.requestUpdateWallpaperIfNeeded();
836 }
837 }
838
Chong Zhangd78ddb42016-03-02 17:01:14 -0800839 boolean isRelaunching() {
840 return mPendingRelaunchCount > 0;
841 }
842
843 void startRelaunching() {
844 if (canFreezeBounds()) {
845 freezeBounds();
846 }
847 mPendingRelaunchCount++;
848 }
849
850 void finishRelaunching() {
851 if (canFreezeBounds()) {
852 unfreezeBounds();
853 }
854 if (mPendingRelaunchCount > 0) {
855 mPendingRelaunchCount--;
856 }
857 }
858
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700859 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700860 if (mPendingRelaunchCount == 0) {
861 return;
862 }
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700863 if (canFreezeBounds()) {
864 unfreezeBounds();
865 }
866 mPendingRelaunchCount = 0;
867 }
868
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700869 @Override
Robert Carra1eb4392015-12-10 12:43:51 -0800870 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700871 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700872
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700873 for (int i = windows.size() - 1; i >= 0; i--) {
874 final WindowState candidate = windows.get(i);
875 if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null
876 && candidate.getWindowTag().toString().equals(w.getWindowTag().toString())) {
877
Robert Carra1eb4392015-12-10 12:43:51 -0800878 candidate.mReplacingWindow = w;
Robert Carrb439a632016-04-07 22:52:10 -0700879 w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow;
Chong Zhangf596cd52016-01-05 13:42:44 -0800880 // if we got a replacement window, reset the timeout to give drawing more time
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700881 mService.scheduleReplacingWindowTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -0800882 }
883 }
Robert Carra1eb4392015-12-10 12:43:51 -0800884 }
885
886 boolean waitingForReplacement() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700887 for (int i = windows.size() - 1; i >= 0; i--) {
888 WindowState candidate = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800889 if (candidate.mWillReplaceWindow) {
890 return true;
891 }
892 }
893 return false;
894 }
895
Chong Zhangf596cd52016-01-05 13:42:44 -0800896 void clearTimedoutReplacesLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700897 for (int i = windows.size() - 1; i >= 0;
898 // WindowState#remove() at bottom of loop may remove multiple entries from windows if
899 // the window to be removed has child windows. It also may not remove any windows from
900 // windows at all if win is exiting and currently animating away. This ensures that
901 // winNdx is monotonically decreasing and never beyond windows bounds.
902 i = Math.min(i - 1, windows.size() - 1)) {
903 final WindowState candidate = windows.get(i);
904 if (!candidate.mWillReplaceWindow) {
Robert Carra1eb4392015-12-10 12:43:51 -0800905 continue;
906 }
907 candidate.mWillReplaceWindow = false;
Robert Carrb439a632016-04-07 22:52:10 -0700908 if (candidate.mReplacingWindow != null) {
909 candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false;
910 }
Chong Zhangf596cd52016-01-05 13:42:44 -0800911 // Since the window already timed out, remove it immediately now.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700912 // Use WindowState#remove() instead of WindowState#removeIfPossible(), as the latter
Chong Zhangf596cd52016-01-05 13:42:44 -0800913 // delays removal on certain conditions, which will leave the stale window in the
914 // stack and marked mWillReplaceWindow=false, so the window will never be removed.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700915 candidate.remove();
Robert Carra1eb4392015-12-10 12:43:51 -0800916 }
917 }
918
Chong Zhangd78ddb42016-03-02 17:01:14 -0800919 private boolean canFreezeBounds() {
920 // For freeform windows, we can't freeze the bounds at the moment because this would make
921 // the resizing unresponsive.
922 return mTask != null && !mTask.inFreeformWorkspace();
923 }
924
Jorim Jaggi0429f352015-12-22 16:29:16 +0100925 /**
926 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
927 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
928 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
929 * with a queue.
930 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800931 private void freezeBounds() {
Jorim Jaggi0429f352015-12-22 16:29:16 +0100932 mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700933
934 if (mTask.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
935 // We didn't call prepareFreezingBounds on the task, so use the current value.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700936 final Configuration config = new Configuration(mService.mCurConfiguration);
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700937 config.updateFrom(mTask.mOverrideConfig);
938 mFrozenMergedConfig.offer(config);
939 } else {
940 mFrozenMergedConfig.offer(new Configuration(mTask.mPreparedFrozenMergedConfig));
941 }
942 mTask.mPreparedFrozenMergedConfig.setToDefaults();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100943 }
944
945 /**
946 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
947 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800948 private void unfreezeBounds() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700949 if (!mFrozenBounds.isEmpty()) {
950 mFrozenBounds.remove();
951 }
952 if (!mFrozenMergedConfig.isEmpty()) {
953 mFrozenMergedConfig.remove();
954 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700955 for (int i = windows.size() - 1; i >= 0; i--) {
956 final WindowState win = windows.get(i);
Jorim Jaggi69abc192016-02-04 19:34:00 -0800957 if (!win.mHasSurface) {
958 continue;
959 }
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100960 win.mLayoutNeeded = true;
961 win.setDisplayLayoutNeeded();
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700962 if (!mService.mResizingWindows.contains(win)) {
963 mService.mResizingWindows.add(win);
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100964 }
965 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700966 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100967 }
968
Robert Carr91b228092016-06-28 17:32:37 -0700969 void addSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
970 mSurfaceViewBackgrounds.add(background);
971 }
972
973 void removeSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
974 mSurfaceViewBackgrounds.remove(background);
975 updateSurfaceViewBackgroundVisibilities();
976 }
977
978 // We use DimLayers behind SurfaceViews to prevent holes while resizing and creating.
979 // However, we need to ensure one SurfaceView doesn't cover another when they are both placed
980 // below the main app window (as traditionally a SurfaceView which is never drawn
981 // to is totally translucent). So we look at all our SurfaceView backgrounds and only enable
982 // the background for the SurfaceView with lowest Z order
983 void updateSurfaceViewBackgroundVisibilities() {
984 WindowSurfaceController.SurfaceControlWithBackground bottom = null;
985 int bottomLayer = Integer.MAX_VALUE;
986 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
987 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
988 if (sc.mVisible && sc.mLayer < bottomLayer) {
989 bottomLayer = sc.mLayer;
990 bottom = sc;
991 }
992 }
993 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
994 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
995 sc.updateBackgroundVisibility(sc != bottom);
996 }
997 }
998
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700999 void resetJustMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001000 for (int i = windows.size() - 1; i >= 0; i--) {
1001 windows.get(i).resetJustMovedInStack();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001002 }
1003 }
1004
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001005 void setWaitingForDrawnIfResizingChanged() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001006 for (int i = windows.size() - 1; i >= 0; --i) {
1007 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001008 if (win.isDragResizeChanged()) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001009 mService.mWaitingForDrawn.add(win);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001010 }
1011 }
1012 }
1013
1014 void resizeWindows() {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001015 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001016 // Some windows won't go through the resizing process, if they don't have a surface, so
1017 // destroy all saved surfaces here.
1018 destroySavedSurfaces();
1019
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001020 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1021 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001022 if (win.mHasSurface && !resizingWindows.contains(win)) {
1023 if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
1024 resizingWindows.add(win);
1025
1026 // If we are not drag resizing, force recreating of a new surface so updating
1027 // the content and positioning that surface will be in sync.
1028 //
1029 // As we use this flag as a hint to freeze surface boundary updates,
1030 // we'd like to only apply this to TYPE_BASE_APPLICATION,
Chong Zhang921f8e32016-08-17 14:26:57 -07001031 // windows of TYPE_APPLICATION (or TYPE_DRAWN_APPLICATION) like dialogs,
1032 // could appear to not be drag resizing while they resize, but we'd
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001033 // still like to manipulate their frame to update crop, etc...
1034 //
1035 // Anyway we don't need to synchronize position and content updates for these
1036 // windows since they aren't at the base layer and could be moved around anyway.
1037 if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
1038 !mTask.mStack.getBoundsAnimating() && !win.isGoneForLayoutLw() &&
1039 !mTask.inPinnedWorkspace()) {
1040 win.setResizedWhileNotDragResizing(true);
1041 }
1042 }
1043 if (win.isGoneForLayoutLw()) {
1044 win.mResizedWhileGone = true;
1045 }
1046 }
1047 }
1048
1049 void moveWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001050 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1051 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001052 if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
1053 win.mMovedByResize = true;
1054 }
1055 }
1056
1057 void notifyMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001058 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1059 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001060 win.notifyMovedInStack();
1061 }
1062 }
1063
1064 void resetDragResizingChangeReported() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001065 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1066 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001067 win.resetDragResizingChangeReported();
1068 }
1069 }
1070
1071 void detachDisplay() {
1072 boolean doAnotherLayoutPass = false;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001073 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001074 // We are in the middle of changing the state of displays/stacks/tasks. We need
1075 // to finish that, before we let layout interfere with it.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001076 windows.get(winNdx).removeIfPossible();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001077 doAnotherLayoutPass = true;
1078 }
1079 if (doAnotherLayoutPass) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001080 mService.mWindowPlacerLocked.requestTraversal();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001081 }
1082 }
1083
1084 void forceWindowsScaleableInTransaction(boolean force) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001085 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1086 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001087 if (winAnimator == null || !winAnimator.hasSurface()) {
1088 continue;
1089 }
1090 winAnimator.mSurfaceController.forceScaleableInTransaction(force);
1091 }
1092 }
1093
1094 boolean isAnimating() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001095 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1096 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001097 if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
1098 return true;
1099 }
1100 }
1101 return false;
1102 }
1103
1104 void setAppLayoutChanges(int changes, String reason, int displayId) {
1105 final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001106 for (int i = windows.size() - 1; i >= 0; i--) {
1107 if (displayId == windows.get(i).getDisplayId()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001108 windowAnimator.setPendingLayoutChanges(displayId, changes);
1109 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001110 mService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001111 reason, windowAnimator.getPendingLayoutChanges(displayId));
1112 }
1113 break;
1114 }
1115 }
1116 }
1117
1118 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001119 for (int i = windows.size() - 1; i >= 0; i--) {
1120 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001121 if (win.mWillReplaceWindow && win.mReplacingWindow == replacement
1122 && replacement.hasDrawnLw()) {
1123 replacement.mSkipEnterAnimationForSeamlessReplacement = false;
1124 win.removeReplacedWindow();
1125 }
1126 }
1127 }
1128
1129 void startFreezingScreen() {
1130 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
1131 + hidden + " freezing=" + mAppAnimator.freezingScreen);
1132 if (!hiddenRequested) {
1133 if (!mAppAnimator.freezingScreen) {
1134 mAppAnimator.freezingScreen = true;
1135 mAppAnimator.lastFreezeDuration = 0;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001136 mService.mAppsFreezingScreen++;
1137 if (mService.mAppsFreezingScreen == 1) {
1138 mService.startFreezingDisplayLocked(false, 0, 0);
1139 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1140 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001141 }
1142 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001143 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001144 for (int i = 0; i < count; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001145 final WindowState w = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001146 w.mAppFreezing = true;
1147 }
1148 }
1149 }
1150
1151 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
1152 if (!mAppAnimator.freezingScreen) {
1153 return;
1154 }
1155 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001156 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001157 boolean unfrozeWindows = false;
1158 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 if (w.mAppFreezing) {
1161 w.mAppFreezing = false;
1162 if (w.mHasSurface && !w.mOrientationChanging
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001163 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001164 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
1165 w.mOrientationChanging = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001166 mService.mWindowPlacerLocked.mOrientationChangeComplete = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001167 }
1168 w.mLastFreezeDuration = 0;
1169 unfrozeWindows = true;
1170 w.setDisplayLayoutNeeded();
1171 }
1172 }
1173 if (force || unfrozeWindows) {
1174 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
1175 mAppAnimator.freezingScreen = false;
1176 mAppAnimator.lastFreezeDuration =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001177 (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime);
1178 mService.mAppsFreezingScreen--;
1179 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001180 }
1181 if (unfreezeSurfaceNow) {
1182 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001183 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001184 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001185 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001186 }
1187 }
1188
1189 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001190 final AppWindowToken fromToken = mService.findAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001191 if (fromToken == null) {
1192 return false;
1193 }
1194
1195 final WindowState tStartingWindow = fromToken.startingWindow;
1196 if (tStartingWindow != null && fromToken.startingView != null) {
1197 // In this case, the starting icon has already been displayed, so start
1198 // letting windows get shown immediately without any more transitions.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001199 mService.mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001200
1201 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1202 + " from " + fromToken + " to " + this);
1203
1204 final long origId = Binder.clearCallingIdentity();
1205
1206 // Transfer the starting window over to the new token.
1207 startingData = fromToken.startingData;
1208 startingView = fromToken.startingView;
1209 startingDisplayed = fromToken.startingDisplayed;
1210 fromToken.startingDisplayed = false;
1211 startingWindow = tStartingWindow;
1212 reportedVisible = fromToken.reportedVisible;
1213 fromToken.startingData = null;
1214 fromToken.startingView = null;
1215 fromToken.startingWindow = null;
1216 fromToken.startingMoved = true;
1217 tStartingWindow.mToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001218 tStartingWindow.mAppToken = this;
1219
1220 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1221 "Removing starting window: " + tStartingWindow);
1222 tStartingWindow.getWindowList().remove(tStartingWindow);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001223 mService.mWindowsChanged = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001224 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1225 "Removing starting " + tStartingWindow + " from " + fromToken);
1226 fromToken.removeWindow(tStartingWindow);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001227 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001228
1229 // Propagate other interesting state between the tokens. If the old token is displayed,
1230 // we should immediately force the new one to be displayed. If it is animating, we need
1231 // to move that animation to the new one.
1232 if (fromToken.allDrawn) {
1233 allDrawn = true;
1234 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1235 }
1236 if (fromToken.firstWindowDrawn) {
1237 firstWindowDrawn = true;
1238 }
1239 if (!fromToken.hidden) {
1240 hidden = false;
1241 hiddenRequested = false;
1242 }
1243 if (clientHidden != fromToken.clientHidden) {
1244 clientHidden = fromToken.clientHidden;
1245 sendAppVisibilityToClients();
1246 }
1247 fromToken.mAppAnimator.transferCurrentAnimation(
1248 mAppAnimator, tStartingWindow.mWinAnimator);
1249
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001250 mService.updateFocusedWindowLocked(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001251 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001252 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1253 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001254 Binder.restoreCallingIdentity(origId);
1255 return true;
1256 } else if (fromToken.startingData != null) {
1257 // The previous app was getting ready to show a
1258 // starting window, but hasn't yet done so. Steal it!
1259 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1260 "Moving pending starting from " + fromToken + " to " + this);
1261 startingData = fromToken.startingData;
1262 fromToken.startingData = null;
1263 fromToken.startingMoved = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001264 final Message m = mService.mH.obtainMessage(H.ADD_STARTING, this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001265 // Note: we really want to do sendMessageAtFrontOfQueue() because we want to process the
1266 // message ASAP, before any other queued messages.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001267 mService.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001268 return true;
1269 }
1270
1271 final AppWindowAnimator tAppAnimator = fromToken.mAppAnimator;
1272 final AppWindowAnimator wAppAnimator = mAppAnimator;
1273 if (tAppAnimator.thumbnail != null) {
1274 // The old token is animating with a thumbnail, transfer that to the new token.
1275 if (wAppAnimator.thumbnail != null) {
1276 wAppAnimator.thumbnail.destroy();
1277 }
1278 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
1279 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
1280 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
1281 tAppAnimator.thumbnail = null;
1282 }
1283 return false;
1284 }
1285
1286 int getWindowsCount() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001287 return windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001288 }
1289
1290 void setAllAppWinAnimators() {
1291 final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
1292 allAppWinAnimators.clear();
1293
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001294 final int windowsCount = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001295 for (int j = 0; j < windowsCount; j++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001296 allAppWinAnimators.add(windows.get(j).mWinAnimator);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001297 }
1298 }
1299
Craig Mautnerdbb79912012-03-01 18:59:14 -08001300 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001301 AppWindowToken asAppWindowToken() {
1302 // I am an app window token!
1303 return this;
1304 }
1305
1306 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001307 void dump(PrintWriter pw, String prefix) {
1308 super.dump(pw, prefix);
1309 if (appToken != null) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001310 pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001311 }
Craig Mautner83162a92015-01-26 14:43:30 -08001312 pw.print(prefix); pw.print("task="); pw.println(mTask);
1313 pw.print(prefix); pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001314 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
1315 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
1316 pw.print(" clientHidden="); pw.print(clientHidden);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07001317 pw.print(" reportedDrawn="); pw.print(reportedDrawn);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001318 pw.print(" reportedVisible="); pw.println(reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07001319 if (paused) {
1320 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001321 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001322 if (mAppStopped) {
1323 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
1324 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001325 if (numInterestingWindows != 0 || numDrawnWindows != 0
Craig Mautner6fbda632012-07-03 09:26:39 -07001326 || allDrawn || mAppAnimator.allDrawn) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001327 pw.print(prefix); pw.print("numInterestingWindows=");
1328 pw.print(numInterestingWindows);
1329 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
1330 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07001331 pw.print(" allDrawn="); pw.print(allDrawn);
1332 pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
1333 pw.println(")");
1334 }
1335 if (inPendingTransaction) {
1336 pw.print(prefix); pw.print("inPendingTransaction=");
1337 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001338 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08001339 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001340 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
1341 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08001342 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08001343 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001344 }
1345 if (startingWindow != null || startingView != null
1346 || startingDisplayed || startingMoved) {
1347 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
1348 pw.print(" startingView="); pw.print(startingView);
1349 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001350 pw.print(" startingMoved="); pw.println(startingMoved);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001351 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01001352 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001353 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001354 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08001355 }
1356 if (mPendingRelaunchCount != 0) {
1357 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01001358 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001359 }
1360
1361 @Override
1362 public String toString() {
1363 if (stringName == null) {
1364 StringBuilder sb = new StringBuilder();
1365 sb.append("AppWindowToken{");
1366 sb.append(Integer.toHexString(System.identityHashCode(this)));
1367 sb.append(" token="); sb.append(token); sb.append('}');
1368 stringName = sb.toString();
1369 }
1370 return stringName;
1371 }
Jeff Browne9bdb312012-04-05 15:30:10 -07001372}