blob: 47f435f0c7cad090f52f99acf1a3b8d367714f7d [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
76 // All of the windows and child windows that are included in this
77 // application token. Note this list is NOT sorted!
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070078 private final WindowList allAppWindows = new WindowList();
Filip Gruszczynskia590c992015-11-25 16:45:26 -080079 @NonNull final AppWindowAnimator mAppAnimator;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070080
Dianne Hackborne30e02f2014-05-27 18:24:45 -070081 final boolean voiceInteraction;
82
Craig Mautner83162a92015-01-26 14:43:30 -080083 Task mTask;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080084 boolean appFullscreen;
85 int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Craig Mautner4c5eb222013-11-18 12:59:05 -080086 boolean layoutConfigChanges;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -070087 boolean showForAllUsers;
Yorke Lee0e852472016-06-15 10:03:18 -070088 int targetSdk;
Craig Mautnera2c77052012-03-26 12:14:43 -070089
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080090 // The input dispatching timeout for this application token in nanoseconds.
91 long inputDispatchingTimeoutNanos;
92
93 // These are used for determining when all windows associated with
94 // an activity have been drawn, so they can be made visible together
95 // at the same time.
Craig Mautner764983d2012-03-22 11:37:36 -070096 // initialize so that it doesn't match mTransactionSequence which is an int.
97 long lastTransactionSequence = Long.MIN_VALUE;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080098 int numInterestingWindows;
99 int numDrawnWindows;
100 boolean inPendingTransaction;
101 boolean allDrawn;
Craig Mautner7636dfb2012-11-16 15:24:11 -0800102 // Set to true when this app creates a surface while in the middle of an animation. In that
103 // case do not clear allDrawn until the animation completes.
104 boolean deferClearAllDrawn;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800105
Chong Zhang8e4bda92016-05-04 15:08:18 -0700106 // These are to track the app's real drawing status if there were no saved surfaces.
107 boolean allDrawnExcludingSaved;
108 int numInterestingWindowsExcludingSaved;
109 int numDrawnWindowsExclusingSaved;
110
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800111 // Is this window's surface needed? This is almost like hidden, except
112 // it will sometimes be true a little earlier: when the token has
113 // been shown, but is still waiting for its app transition to execute
114 // before making its windows shown.
115 boolean hiddenRequested;
116
117 // Have we told the window clients to hide themselves?
118 boolean clientHidden;
119
120 // Last visibility state we reported to the app token.
121 boolean reportedVisible;
122
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700123 // Last drawn state we reported to the app token.
124 boolean reportedDrawn;
125
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800126 // Set to true when the token has been removed from the window mgr.
127 boolean removed;
128
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800129 // Information about an application starting window if displayed.
130 StartingData startingData;
131 WindowState startingWindow;
132 View startingView;
133 boolean startingDisplayed;
134 boolean startingMoved;
135 boolean firstWindowDrawn;
136
137 // Input application handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700138 final InputApplicationHandle mInputApplicationHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800139
Craig Mautner799bc1d2015-01-14 10:33:48 -0800140 boolean mIsExiting;
Craig Mautner9ef471f2014-02-07 13:11:47 -0800141
Craig Mautnerbb742462014-07-07 15:28:55 -0700142 boolean mLaunchTaskBehind;
Craig Mautner8746a472014-07-24 15:12:54 -0700143 boolean mEnteringAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -0700144
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800145 boolean mAlwaysFocusable;
146
Robert Carre12aece2016-02-02 22:43:27 -0800147 boolean mAppStopped;
Robert Carrfd10cd12016-06-29 16:41:50 -0700148 int mRotationAnimationHint;
Chong Zhangd78ddb42016-03-02 17:01:14 -0800149 int mPendingRelaunchCount;
Robert Carre12aece2016-02-02 22:43:27 -0800150
Robert Carr91b228092016-06-28 17:32:37 -0700151 private ArrayList<WindowSurfaceController.SurfaceControlWithBackground> mSurfaceViewBackgrounds =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700152 new ArrayList<>();
Robert Carr91b228092016-06-28 17:32:37 -0700153
Jorim Jaggi0429f352015-12-22 16:29:16 +0100154 ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700155 ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100156
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700157 AppWindowToken(WindowManagerService service, IApplicationToken _token, boolean _voiceInteraction) {
158 super(service, _token.asBinder(), WindowManager.LayoutParams.TYPE_APPLICATION, true);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800159 appToken = _token;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700160 voiceInteraction = _voiceInteraction;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800161 mInputApplicationHandle = new InputApplicationHandle(this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700162 mAppAnimator = new AppWindowAnimator(this, service);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800163 }
164
165 void sendAppVisibilityToClients() {
166 final int N = allAppWindows.size();
167 for (int i=0; i<N; i++) {
168 WindowState win = allAppWindows.get(i);
169 if (win == startingWindow && clientHidden) {
170 // Don't hide the starting window.
171 continue;
172 }
173 try {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800174 if (DEBUG_VISIBILITY) Slog.v(TAG,
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800175 "Setting visibility of " + win + ": " + (!clientHidden));
176 win.mClient.dispatchAppVisibility(!clientHidden);
177 } catch (RemoteException e) {
178 }
179 }
180 }
181
Chong Zhang92147042016-05-09 12:47:11 -0700182 void setVisibleBeforeClientHidden() {
183 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
184 final WindowState w = allAppWindows.get(i);
185 w.setVisibleBeforeClientHidden();
186 }
187 }
188
Wale Ogunwale9017ec02016-02-25 08:55:25 -0800189 void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
190 firstWindowDrawn = true;
191
192 // We now have a good window to show, remove dead placeholders
193 removeAllDeadWindows();
194
195 if (startingData != null) {
196 if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
197 + win.mToken + ": first real window is shown, no animation");
198 // If this initial window is animating, stop it -- we will do an animation to reveal
199 // it from behind the starting window, so there is no need for it to also be doing its
200 // own stuff.
201 winAnimator.clearAnimation();
202 winAnimator.mService.mFinishedStarting.add(this);
203 winAnimator.mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
204 }
205 updateReportedVisibilityLocked();
206 }
207
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800208 void updateReportedVisibilityLocked() {
209 if (appToken == null) {
210 return;
211 }
212
213 int numInteresting = 0;
214 int numVisible = 0;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700215 int numDrawn = 0;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800216 boolean nowGone = true;
217
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800218 if (DEBUG_VISIBILITY) Slog.v(TAG,
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700219 "Update reported visibility: " + this);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800220 final int N = allAppWindows.size();
221 for (int i=0; i<N; i++) {
222 WindowState win = allAppWindows.get(i);
223 if (win == startingWindow || win.mAppFreezing
224 || win.mViewVisibility != View.VISIBLE
225 || win.mAttrs.type == TYPE_APPLICATION_STARTING
226 || win.mDestroying) {
227 continue;
228 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800229 if (DEBUG_VISIBILITY) {
230 Slog.v(TAG, "Win " + win + ": isDrawn="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800231 + win.isDrawnLw()
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700232 + ", isAnimationSet=" + win.mWinAnimator.isAnimationSet());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800233 if (!win.isDrawnLw()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800234 Slog.v(TAG, "Not displayed: s=" +
Robert Carre6a83512015-11-03 16:09:21 -0800235 win.mWinAnimator.mSurfaceController
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800236 + " pv=" + win.mPolicyVisibility
Craig Mautner749a7bb2012-04-02 13:49:53 -0700237 + " mDrawState=" + win.mWinAnimator.mDrawState
Wale Ogunwale9d147902016-07-16 11:58:55 -0700238 + " ph=" + win.isParentWindowHidden()
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800239 + " th="
240 + (win.mAppToken != null
241 ? win.mAppToken.hiddenRequested : false)
Craig Mautnera2c77052012-03-26 12:14:43 -0700242 + " a=" + win.mWinAnimator.mAnimating);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800243 }
244 }
245 numInteresting++;
246 if (win.isDrawnLw()) {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700247 numDrawn++;
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700248 if (!win.mWinAnimator.isAnimationSet()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800249 numVisible++;
250 }
251 nowGone = false;
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700252 } else if (win.mWinAnimator.isAnimationSet()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800253 nowGone = false;
254 }
255 }
256
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700257 boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800258 boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700259 if (!nowGone) {
260 // If the app is not yet gone, then it can only become visible/drawn.
261 if (!nowDrawn) {
262 nowDrawn = reportedDrawn;
263 }
264 if (!nowVisible) {
265 nowVisible = reportedVisible;
266 }
267 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800268 if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800269 + numInteresting + " visible=" + numVisible);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700270 if (nowDrawn != reportedDrawn) {
271 if (nowDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700272 Message m = mService.mH.obtainMessage(
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700273 H.REPORT_APPLICATION_TOKEN_DRAWN, this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700274 mService.mH.sendMessage(m);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -0700275 }
276 reportedDrawn = nowDrawn;
277 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800278 if (nowVisible != reportedVisible) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800279 if (DEBUG_VISIBILITY) Slog.v(
280 TAG, "Visibility changed in " + this
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800281 + ": vis=" + nowVisible);
282 reportedVisible = nowVisible;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700283 Message m = mService.mH.obtainMessage(
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800284 H.REPORT_APPLICATION_TOKEN_WINDOWS,
285 nowVisible ? 1 : 0,
286 nowGone ? 1 : 0,
287 this);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700288 mService.mH.sendMessage(m);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800289 }
290 }
291
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700292 boolean setVisibility(WindowManager.LayoutParams lp,
293 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
294
295 boolean delayed = false;
296 inPendingTransaction = false;
297
298 if (clientHidden == visible) {
299 clientHidden = !visible;
300 sendAppVisibilityToClients();
301 }
302
303 // Allow for state changes and animation to be applied if:
304 // * token is transitioning visibility state
305 // * or the token was marked as hidden and is exiting before we had a chance to play the
306 // transition animation
307 // * or this is an opening app and windows are being replaced.
308 boolean visibilityChanged = false;
309 if (hidden == visible || (hidden && mIsExiting) || (visible && waitingForReplacement())) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700310 final AccessibilityController accessibilityController = mService.mAccessibilityController;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700311 boolean changed = false;
312 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
313 "Changing app " + this + " hidden=" + hidden + " performLayout=" + performLayout);
314
315 boolean runningAppAnimation = false;
316
317 if (transit != AppTransition.TRANSIT_UNSET) {
318 if (mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
319 mAppAnimator.setNullAnimation();
320 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700321 if (mService.applyAnimationLocked(this, lp, transit, visible, isVoiceInteraction)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700322 delayed = runningAppAnimation = true;
323 }
324 final WindowState window = findMainWindow();
325 //TODO (multidisplay): Magnification is supported only for the default display.
326 if (window != null && accessibilityController != null
327 && window.getDisplayId() == DEFAULT_DISPLAY) {
328 accessibilityController.onAppWindowTransitionLocked(window, transit);
329 }
330 changed = true;
331 }
332
333 final int windowsCount = allAppWindows.size();
334 for (int i = 0; i < windowsCount; i++) {
335 final WindowState win = allAppWindows.get(i);
336 if (win == startingWindow) {
337 // Starting window that's exiting will be removed when the animation finishes.
338 // Mark all relevant flags for that onExitAnimationDone will proceed all the way
339 // to actually remove it.
340 if (!visible && win.isVisibleNow() && mAppAnimator.isAnimating()) {
341 win.mAnimatingExit = true;
342 win.mRemoveOnExit = true;
343 win.mWindowRemovalAllowed = true;
344 }
345 continue;
346 }
347
348 //Slog.i(TAG_WM, "Window " + win + ": vis=" + win.isVisible());
349 //win.dump(" ");
350 if (visible) {
351 if (!win.isVisibleNow()) {
352 if (!runningAppAnimation) {
353 win.mWinAnimator.applyAnimationLocked(TRANSIT_ENTER, true);
354 //TODO (multidisplay): Magnification is supported only for the default
355 if (accessibilityController != null
356 && win.getDisplayId() == DEFAULT_DISPLAY) {
357 accessibilityController.onWindowTransitionLocked(win, TRANSIT_ENTER);
358 }
359 }
360 changed = true;
361 win.setDisplayLayoutNeeded();
362 }
363 } else if (win.isVisibleNow()) {
364 if (!runningAppAnimation) {
365 win.mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false);
366 //TODO (multidisplay): Magnification is supported only for the default
367 if (accessibilityController != null
368 && win.getDisplayId() == DEFAULT_DISPLAY) {
369 accessibilityController.onWindowTransitionLocked(win,TRANSIT_EXIT);
370 }
371 }
372 changed = true;
373 win.setDisplayLayoutNeeded();
374 }
375 }
376
377 hidden = hiddenRequested = !visible;
378 visibilityChanged = true;
379 if (!visible) {
380 stopFreezingScreen(true, true);
381 } else {
382 // If we are being set visible, and the starting window is
383 // not yet displayed, then make sure it doesn't get displayed.
384 WindowState swin = startingWindow;
385 if (swin != null && !swin.isDrawnLw()) {
386 swin.mPolicyVisibility = false;
387 swin.mPolicyVisibilityAfterAnim = false;
388 }
389 }
390
391 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setVisibility: " + this
392 + ": hidden=" + hidden + " hiddenRequested=" + hiddenRequested);
393
394 if (changed) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700395 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700396 if (performLayout) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700397 mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700398 false /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700399 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700400 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700401 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700402 }
403 }
404
405 if (mAppAnimator.animation != null) {
406 delayed = true;
407 }
408
409 for (int i = allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
410 if (allAppWindows.get(i).mWinAnimator.isWindowAnimationSet()) {
411 delayed = true;
412 }
413 }
414
415 if (visibilityChanged) {
416 if (visible && !delayed) {
417 // The token was made immediately visible, there will be no entrance animation.
418 // We need to inform the client the enter animation was finished.
419 mEnteringAnimation = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700420 mService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700421 }
422
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700423 if (!mService.mClosingApps.contains(this) && !mService.mOpeningApps.contains(this)) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700424 // The token is not closing nor opening, so even if there is an animation set, that
425 // doesn't mean that it goes through the normal app transition cycle so we have
426 // to inform the docked controller about visibility change.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700427 mService.getDefaultDisplayContentLocked().getDockedDividerController()
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700428 .notifyAppVisibilityChanged();
429 }
430 }
431
432 return delayed;
433 }
434
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800435 WindowState findMainWindow() {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700436 WindowState candidate = null;
Wale Ogunwale455fac52016-07-21 07:24:49 -0700437 int j = allAppWindows.size();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800438 while (j > 0) {
439 j--;
Wale Ogunwale455fac52016-07-21 07:24:49 -0700440 WindowState win = allAppWindows.get(j);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800441 if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
442 || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700443 // In cases where there are multiple windows, we prefer the non-exiting window. This
Sungsoo Lim0d3d1f82015-12-02 14:47:59 +0900444 // happens for example when replacing windows during an activity relaunch. When
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700445 // constructing the animation, we want the new window, not the exiting one.
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800446 if (win.mAnimatingExit) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700447 candidate = win;
448 } else {
449 return win;
450 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800451 }
452 }
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700453 return candidate;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800454 }
455
Wale Ogunwale6cae7652015-12-26 07:36:26 -0800456 boolean windowsAreFocusable() {
457 return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
Wale Ogunwaled045c822015-12-02 09:14:28 -0800458 }
459
Craig Mautner72669d12012-12-18 17:23:54 -0800460 boolean isVisible() {
461 final int N = allAppWindows.size();
Craig Mautner72669d12012-12-18 17:23:54 -0800462 for (int i=0; i<N; i++) {
463 WindowState win = allAppWindows.get(i);
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700464 // If we're animating with a saved surface, we're already visible.
465 // Return true so that the alpha doesn't get cleared.
Craig Mautner72669d12012-12-18 17:23:54 -0800466 if (!win.mAppFreezing
Chong Zhang92147042016-05-09 12:47:11 -0700467 && (win.mViewVisibility == View.VISIBLE || win.isAnimatingWithSavedSurface()
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700468 || (win.mWinAnimator.isAnimationSet()
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700469 && !mService.mAppTransition.isTransitionSet()))
Filip Gruszczynski57f76f12015-11-04 16:10:54 -0800470 && !win.mDestroying
471 && win.isDrawnLw()) {
Craig Mautner72669d12012-12-18 17:23:54 -0800472 return true;
473 }
474 }
475 return false;
476 }
477
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700478 boolean isVisibleForUser() {
479 for (int j = allAppWindows.size() - 1; j >= 0; j--) {
480 final WindowState w = allAppWindows.get(j);
481 if (!w.isHiddenFromUserLocked()) {
482 return true;
483 }
484 }
485 return false;
486 }
487
Craig Mautnere3119b72015-01-20 15:02:36 -0800488 void removeAppFromTaskLocked() {
489 mIsExiting = false;
490 removeAllWindows();
491
Craig Mautner83162a92015-01-26 14:43:30 -0800492 // Use local variable because removeAppToken will null out mTask.
493 final Task task = mTask;
Craig Mautnere3119b72015-01-20 15:02:36 -0800494 if (task != null) {
495 if (!task.removeAppToken(this)) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800496 Slog.e(TAG, "removeAppFromTaskLocked: token=" + this
Craig Mautnere3119b72015-01-20 15:02:36 -0800497 + " not found.");
498 }
499 task.mStack.mExitingAppTokens.remove(this);
500 }
501 }
502
Chong Zhange05bcb12016-07-26 17:47:29 -0700503 void clearAnimatingFlags() {
504 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
505 final WindowState win = allAppWindows.get(i);
506 // 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) {
514 win.mAnimatingExit = false;
515 // Clear mAnimating flag together with mAnimatingExit. When animation
516 // changes from exiting to entering, we need to clear this flag until the
517 // new animation gets applied, so that isAnimationStarting() becomes true
518 // until then.
519 // Otherwise applySurfaceChangesTransaction will faill to skip surface
520 // placement for this window during this period, one or more frame will
521 // show up with wrong position or scale.
522 win.mWinAnimator.mAnimating = false;
523 }
524 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700525 requestUpdateWallpaperIfNeeded();
Chong Zhange05bcb12016-07-26 17:47:29 -0700526 }
527
Robert Carre12aece2016-02-02 22:43:27 -0800528 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700529 destroySurfaces(false /*cleanupOnResume*/);
530 }
531
532 /**
533 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
534 * the client has finished with them.
535 *
536 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
537 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
538 * others so that they are ready to be reused. If set to false (common case), destroy all
539 * surfaces that's eligible, if the app is already stopped.
540 */
541
542 private void destroySurfaces(boolean cleanupOnResume) {
Robert Carre12aece2016-02-02 22:43:27 -0800543 final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) allAppWindows.clone();
544 final DisplayContentList displayList = new DisplayContentList();
545 for (int i = allWindows.size() - 1; i >= 0; i--) {
546 final WindowState win = allWindows.get(i);
Chong Zhangeb665572016-05-09 18:28:27 -0700547
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700548 if (!(mAppStopped || win.mWindowRemovalAllowed || cleanupOnResume)) {
Robert Carre12aece2016-02-02 22:43:27 -0800549 continue;
550 }
551
Chong Zhangeb665572016-05-09 18:28:27 -0700552 win.mWinAnimator.destroyPreservedSurfaceLocked();
553
554 if (!win.mDestroying) {
Chong Zhang5471e902016-02-12 15:34:10 -0800555 continue;
Robert Carre12aece2016-02-02 22:43:27 -0800556 }
557
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800558 if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + win
559 + " destroySurfaces: mAppStopped=" + mAppStopped
560 + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed
561 + " win.mRemoveOnExit=" + win.mRemoveOnExit);
562
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700563 if (!cleanupOnResume || win.mRemoveOnExit) {
564 win.destroyOrSaveSurface();
565 }
Robert Carre12aece2016-02-02 22:43:27 -0800566 if (win.mRemoveOnExit) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700567 win.remove();
Robert Carre12aece2016-02-02 22:43:27 -0800568 }
569 final DisplayContent displayContent = win.getDisplayContent();
570 if (displayContent != null && !displayList.contains(displayContent)) {
571 displayList.add(displayContent);
572 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700573 if (cleanupOnResume) {
574 win.requestUpdateWallpaperIfNeeded();
575 }
Robert Carre12aece2016-02-02 22:43:27 -0800576 win.mDestroying = false;
577 }
578 for (int i = 0; i < displayList.size(); i++) {
579 final DisplayContent displayContent = displayList.get(i);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700580 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Robert Carre12aece2016-02-02 22:43:27 -0800581 displayContent.layoutNeeded = true;
582 }
583 }
584
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800585 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700586 * Notify that the app is now resumed, and it was not stopped before, perform a clean
587 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800588 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700589 void notifyAppResumed(boolean wasStopped) {
590 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this);
591 mAppStopped = false;
592 if (!wasStopped) {
593 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800594 }
Robert Carre12aece2016-02-02 22:43:27 -0800595 }
596
Chong Zhangbef461f2015-10-27 11:38:24 -0700597 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700598 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
599 * keeping alive in case they were still being used.
600 */
601 void notifyAppStopped() {
602 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
603 mAppStopped = true;
604 destroySurfaces();
605 // Remove any starting window that was added for this app if they are still around.
606 mTask.mService.scheduleRemoveStartingWindowLocked(this);
607 }
608
609 /**
Chong Zhangbef461f2015-10-27 11:38:24 -0700610 * Checks whether we should save surfaces for this app.
611 *
612 * @return true if the surfaces should be saved, false otherwise.
613 */
614 boolean shouldSaveSurface() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800615 // We want to save surface if the app's windows are "allDrawn".
616 // (If we started entering animation early with saved surfaces, allDrawn
617 // should have been restored to true. So we'll save again in that case
618 // even if app didn't actually finish drawing.)
619 return allDrawn;
Robert Carr13f7be9e2015-12-02 18:39:45 -0800620 }
621
Chong Zhang92147042016-05-09 12:47:11 -0700622 boolean canRestoreSurfaces() {
Chong Zhangb7b4a562016-04-28 15:30:33 -0700623 for (int i = allAppWindows.size() -1; i >= 0; i--) {
Chong Zhang92147042016-05-09 12:47:11 -0700624 final WindowState w = allAppWindows.get(i);
625 if (w.canRestoreSurface()) {
Robert Carr13f7be9e2015-12-02 18:39:45 -0800626 return true;
627 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700628 }
629 return false;
630 }
631
Chong Zhang92147042016-05-09 12:47:11 -0700632 void clearVisibleBeforeClientHidden() {
633 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
634 final WindowState w = allAppWindows.get(i);
635 w.clearVisibleBeforeClientHidden();
636 }
637 }
638
Chong Zhang8e4bda92016-05-04 15:08:18 -0700639 /**
640 * Whether the app has some window that is invisible in layout, but
641 * animating with saved surface.
642 */
643 boolean isAnimatingInvisibleWithSavedSurface() {
644 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
645 final WindowState w = allAppWindows.get(i);
646 if (w.isAnimatingInvisibleWithSavedSurface()) {
647 return true;
648 }
649 }
650 return false;
651 }
652
653 /**
654 * Hide all window surfaces that's still invisible in layout but animating
655 * with a saved surface, and mark them destroying.
656 */
657 void stopUsingSavedSurfaceLocked() {
658 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
659 final WindowState w = allAppWindows.get(i);
660 if (w.isAnimatingInvisibleWithSavedSurface()) {
661 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
662 "stopUsingSavedSurfaceLocked: " + w);
663 w.clearAnimatingWithSavedSurface();
664 w.mDestroying = true;
665 w.mWinAnimator.hide("stopUsingSavedSurfaceLocked");
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700666 mService.mWallpaperControllerLocked.hideWallpapers(w);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700667 }
668 }
669 destroySurfaces();
670 }
671
Chong Zhangf58631a2016-05-24 16:02:10 -0700672 void markSavedSurfaceExiting() {
673 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
674 final WindowState w = allAppWindows.get(i);
675 if (w.isAnimatingInvisibleWithSavedSurface()) {
676 w.mAnimatingExit = true;
677 w.mWinAnimator.mAnimating = true;
678 }
679 }
680 }
681
Chong Zhangbef461f2015-10-27 11:38:24 -0700682 void restoreSavedSurfaces() {
Chong Zhang92147042016-05-09 12:47:11 -0700683 if (!canRestoreSurfaces()) {
684 clearVisibleBeforeClientHidden();
Chong Zhangbef461f2015-10-27 11:38:24 -0700685 return;
686 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800687 // Check if we have enough drawn windows to mark allDrawn= true.
688 int numInteresting = 0;
689 int numDrawn = 0;
Chong Zhangb7b4a562016-04-28 15:30:33 -0700690 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
691 WindowState w = allAppWindows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700692 if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800693 && (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
694 numInteresting++;
Chong Zhang92147042016-05-09 12:47:11 -0700695 if (w.hasSavedSurface()) {
696 w.restoreSavedSurface();
697 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800698 if (w.isDrawnLw()) {
699 numDrawn++;
700 }
701 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700702 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800703
Chong Zhang92147042016-05-09 12:47:11 -0700704 if (!allDrawn) {
705 allDrawn = (numInteresting > 0) && (numInteresting == numDrawn);
706 if (allDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700707 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Chong Zhang92147042016-05-09 12:47:11 -0700708 }
709 }
710 clearVisibleBeforeClientHidden();
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800711
712 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
Wale Ogunwale455fac52016-07-21 07:24:49 -0700713 "restoreSavedSurfaces: " + this + " allDrawn=" + allDrawn
Chong Zhang92147042016-05-09 12:47:11 -0700714 + " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
Chong Zhangbef461f2015-10-27 11:38:24 -0700715 }
716
717 void destroySavedSurfaces() {
Chong Zhangb7b4a562016-04-28 15:30:33 -0700718 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
719 WindowState win = allAppWindows.get(i);
Robert Carr13f7be9e2015-12-02 18:39:45 -0800720 win.destroySavedSurface();
Chong Zhangbef461f2015-10-27 11:38:24 -0700721 }
Chong Zhang92147042016-05-09 12:47:11 -0700722 }
723
724 void clearAllDrawn() {
725 allDrawn = false;
726 deferClearAllDrawn = false;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700727 allDrawnExcludingSaved = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700728 }
729
Wale Ogunwale98e70d02014-11-10 12:12:27 -0800730 @Override
Craig Mautner7c9ee192014-08-14 16:08:26 -0700731 void removeAllWindows() {
Craig Mautner7b4655d2014-11-20 12:13:22 -0800732 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
733 // removeWindowLocked at bottom of loop may remove multiple entries from
734 // allAppWindows if the window to be removed has child windows. It also may
735 // not remove any windows from allAppWindows at all if win is exiting and
736 // currently animating away. This ensures that winNdx is monotonically decreasing
737 // and never beyond allAppWindows bounds.
738 winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
739 WindowState win = allAppWindows.get(winNdx);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800740 if (DEBUG_WINDOW_MOVEMENT) {
741 Slog.w(TAG, "removeAllWindows: removing win=" + win);
Wale Ogunwale98e70d02014-11-10 12:12:27 -0800742 }
743
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700744 mService.removeWindowLocked(win);
Craig Mautner7c9ee192014-08-14 16:08:26 -0700745 }
Craig Mautnere3119b72015-01-20 15:02:36 -0800746 allAppWindows.clear();
747 windows.clear();
Craig Mautner7c9ee192014-08-14 16:08:26 -0700748 }
749
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700750 @Override
751 void removeWindow(WindowState win) {
752 super.removeWindow(win);
753
754 allAppWindows.remove(win);
755
756 if (startingWindow == win) {
757 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700758 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700759 } else if (allAppWindows.size() == 0 && startingData != null) {
760 // If this is the last window and we had requested a starting transition window,
761 // well there is no point now.
762 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
763 startingData = null;
764 } else if (allAppWindows.size() == 1 && startingView != null) {
765 // If this is the last window except for a starting transition window,
766 // we need to get rid of the starting transition.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700767 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700768 }
769 }
770
Chong Zhang112eb8c2015-11-02 11:17:00 -0800771 void removeAllDeadWindows() {
772 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700773 // removeWindowLocked at bottom of loop may remove multiple entries from
774 // allAppWindows if the window to be removed has child windows. It also may
775 // not remove any windows from allAppWindows at all if win is exiting and
776 // currently animating away. This ensures that winNdx is monotonically decreasing
777 // and never beyond allAppWindows bounds.
778 winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800779 WindowState win = allAppWindows.get(winNdx);
780 if (win.mAppDied) {
Wale Ogunwale2728bf42016-03-03 11:03:26 -0800781 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800782 Slog.w(TAG, "removeAllDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800783 }
784 // Set mDestroying, we don't want any animation or delayed removal here.
785 win.mDestroying = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700786 mService.removeWindowLocked(win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800787 }
788 }
789 }
790
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700791 boolean hasWindowsAlive() {
792 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
793 if (!allAppWindows.get(i).mAppDied) {
794 return true;
795 }
796 }
797 return false;
798 }
799
Robert Carra1eb4392015-12-10 12:43:51 -0800800 void setReplacingWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700801 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
802 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800803
804 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
805 final WindowState w = allAppWindows.get(i);
806 w.setReplacing(animate);
807 }
808 if (animate) {
809 // Set-up dummy animation so we can start treating windows associated with this
810 // token like they are in transition before the new app window is ready for us to
811 // run the real transition animation.
812 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
813 "setReplacingWindow() Setting dummy animation on: " + this);
814 mAppAnimator.setDummyAnimation();
815 }
816 }
817
Robert Carr23fa16b2016-01-13 13:19:58 -0800818 void setReplacingChildren() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700819 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800820 + " with replacing child windows.");
821 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
822 final WindowState w = allAppWindows.get(i);
Robert Carrd1a010f2016-04-07 22:36:22 -0700823 if (w.shouldBeReplacedWithChildren()) {
Robert Carr23fa16b2016-01-13 13:19:58 -0800824 w.setReplacing(false /* animate */);
825 }
826 }
827 }
828
Chong Zhangf596cd52016-01-05 13:42:44 -0800829 void resetReplacingWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700830 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
831 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800832
833 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
834 final WindowState w = allAppWindows.get(i);
835 w.resetReplacing();
836 }
837 }
838
Chong Zhang4d7369a2016-04-25 16:09:14 -0700839 void requestUpdateWallpaperIfNeeded() {
840 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
841 final WindowState w = allAppWindows.get(i);
842 w.requestUpdateWallpaperIfNeeded();
843 }
844 }
845
Chong Zhangd78ddb42016-03-02 17:01:14 -0800846 boolean isRelaunching() {
847 return mPendingRelaunchCount > 0;
848 }
849
850 void startRelaunching() {
851 if (canFreezeBounds()) {
852 freezeBounds();
853 }
854 mPendingRelaunchCount++;
855 }
856
857 void finishRelaunching() {
858 if (canFreezeBounds()) {
859 unfreezeBounds();
860 }
861 if (mPendingRelaunchCount > 0) {
862 mPendingRelaunchCount--;
863 }
864 }
865
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700866 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700867 if (mPendingRelaunchCount == 0) {
868 return;
869 }
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700870 if (canFreezeBounds()) {
871 unfreezeBounds();
872 }
873 mPendingRelaunchCount = 0;
874 }
875
Robert Carra1eb4392015-12-10 12:43:51 -0800876 void addWindow(WindowState w) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700877 if (allAppWindows.contains(w)) {
878 return;
879 }
880
Robert Carra1eb4392015-12-10 12:43:51 -0800881 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
882 WindowState candidate = allAppWindows.get(i);
883 if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null &&
Robert Carr8bc89072016-04-08 13:29:59 -0700884 candidate.getWindowTag().toString().equals(w.getWindowTag().toString())) {
Robert Carra1eb4392015-12-10 12:43:51 -0800885 candidate.mReplacingWindow = w;
Robert Carrb439a632016-04-07 22:52:10 -0700886 w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow;
Chong Zhangf596cd52016-01-05 13:42:44 -0800887
888 // if we got a replacement window, reset the timeout to give drawing more time
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700889 mService.scheduleReplacingWindowTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -0800890 }
891 }
892 allAppWindows.add(w);
893 }
894
895 boolean waitingForReplacement() {
896 for (int i = allAppWindows.size() -1; i >= 0; i--) {
897 WindowState candidate = allAppWindows.get(i);
898 if (candidate.mWillReplaceWindow) {
899 return true;
900 }
901 }
902 return false;
903 }
904
Chong Zhangf596cd52016-01-05 13:42:44 -0800905 void clearTimedoutReplacesLocked() {
Robert Carra1eb4392015-12-10 12:43:51 -0800906 for (int i = allAppWindows.size() - 1; i >= 0;
907 // removeWindowLocked at bottom of loop may remove multiple entries from
908 // allAppWindows if the window to be removed has child windows. It also may
909 // not remove any windows from allAppWindows at all if win is exiting and
910 // currently animating away. This ensures that winNdx is monotonically decreasing
911 // and never beyond allAppWindows bounds.
912 i = Math.min(i - 1, allAppWindows.size() - 1)) {
913 WindowState candidate = allAppWindows.get(i);
914 if (candidate.mWillReplaceWindow == false) {
915 continue;
916 }
917 candidate.mWillReplaceWindow = false;
Robert Carrb439a632016-04-07 22:52:10 -0700918 if (candidate.mReplacingWindow != null) {
919 candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false;
920 }
Chong Zhangf596cd52016-01-05 13:42:44 -0800921 // Since the window already timed out, remove it immediately now.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700922 // Use WindowState#remove() instead of removeWindowLocked(), as the latter
Chong Zhangf596cd52016-01-05 13:42:44 -0800923 // delays removal on certain conditions, which will leave the stale window in the
924 // stack and marked mWillReplaceWindow=false, so the window will never be removed.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700925 candidate.remove();
Robert Carra1eb4392015-12-10 12:43:51 -0800926 }
927 }
928
Chong Zhangd78ddb42016-03-02 17:01:14 -0800929 private boolean canFreezeBounds() {
930 // For freeform windows, we can't freeze the bounds at the moment because this would make
931 // the resizing unresponsive.
932 return mTask != null && !mTask.inFreeformWorkspace();
933 }
934
Jorim Jaggi0429f352015-12-22 16:29:16 +0100935 /**
936 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
937 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
938 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
939 * with a queue.
940 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800941 private void freezeBounds() {
Jorim Jaggi0429f352015-12-22 16:29:16 +0100942 mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700943
944 if (mTask.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
945 // We didn't call prepareFreezingBounds on the task, so use the current value.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700946 final Configuration config = new Configuration(mService.mCurConfiguration);
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700947 config.updateFrom(mTask.mOverrideConfig);
948 mFrozenMergedConfig.offer(config);
949 } else {
950 mFrozenMergedConfig.offer(new Configuration(mTask.mPreparedFrozenMergedConfig));
951 }
952 mTask.mPreparedFrozenMergedConfig.setToDefaults();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100953 }
954
955 /**
956 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
957 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800958 private void unfreezeBounds() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700959 if (!mFrozenBounds.isEmpty()) {
960 mFrozenBounds.remove();
961 }
962 if (!mFrozenMergedConfig.isEmpty()) {
963 mFrozenMergedConfig.remove();
964 }
Wale Ogunwale455fac52016-07-21 07:24:49 -0700965 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
966 final WindowState win = allAppWindows.get(i);
Jorim Jaggi69abc192016-02-04 19:34:00 -0800967 if (!win.mHasSurface) {
968 continue;
969 }
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100970 win.mLayoutNeeded = true;
971 win.setDisplayLayoutNeeded();
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700972 if (!mService.mResizingWindows.contains(win)) {
973 mService.mResizingWindows.add(win);
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100974 }
975 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700976 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100977 }
978
Robert Carr91b228092016-06-28 17:32:37 -0700979 void addSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
980 mSurfaceViewBackgrounds.add(background);
981 }
982
983 void removeSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
984 mSurfaceViewBackgrounds.remove(background);
985 updateSurfaceViewBackgroundVisibilities();
986 }
987
988 // We use DimLayers behind SurfaceViews to prevent holes while resizing and creating.
989 // However, we need to ensure one SurfaceView doesn't cover another when they are both placed
990 // below the main app window (as traditionally a SurfaceView which is never drawn
991 // to is totally translucent). So we look at all our SurfaceView backgrounds and only enable
992 // the background for the SurfaceView with lowest Z order
993 void updateSurfaceViewBackgroundVisibilities() {
994 WindowSurfaceController.SurfaceControlWithBackground bottom = null;
995 int bottomLayer = Integer.MAX_VALUE;
996 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
997 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
998 if (sc.mVisible && sc.mLayer < bottomLayer) {
999 bottomLayer = sc.mLayer;
1000 bottom = sc;
1001 }
1002 }
1003 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
1004 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
1005 sc.updateBackgroundVisibility(sc != bottom);
1006 }
1007 }
1008
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001009 void resetJustMovedInStack() {
1010 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
1011 allAppWindows.get(i).resetJustMovedInStack();
1012 }
1013 }
1014
1015 @Override
1016 int adjustAnimLayer(int adj) {
1017 int highestAnimLayer = super.adjustAnimLayer(adj);
1018
1019 final int windowCount = allAppWindows.size();
1020
1021 for (int i = 0; i < windowCount; i++) {
1022 final WindowState w = allAppWindows.get(i);
1023 w.adjustAnimLayer(adj);
1024
1025 final int animLayer = w.mWinAnimator.mAnimLayer;
1026 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + animLayer);
1027 if (animLayer > highestAnimLayer) {
1028 highestAnimLayer = animLayer;
1029 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001030 if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
1031 mService.mLayersController.setInputMethodAnimLayerAdjustment(adj);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001032 }
1033 }
1034
1035 return highestAnimLayer;
1036 }
1037
1038 @Override
1039 int getHighestAnimLayer() {
1040 int layer = super.getHighestAnimLayer();
1041 for (int j = 0; j < allAppWindows.size(); j++) {
1042 final WindowState win = allAppWindows.get(j);
1043 if (win.mWinAnimator.mAnimLayer > layer) {
1044 layer = win.mWinAnimator.mAnimLayer;
1045 }
1046 }
1047 return layer;
1048 }
1049
1050 void setWaitingForDrawnIfResizingChanged() {
1051 for (int i = allAppWindows.size() - 1; i >= 0; --i) {
1052 final WindowState win = allAppWindows.get(i);
1053 if (win.isDragResizeChanged()) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001054 mService.mWaitingForDrawn.add(win);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001055 }
1056 }
1057 }
1058
1059 void resizeWindows() {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001060 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001061 // Some windows won't go through the resizing process, if they don't have a surface, so
1062 // destroy all saved surfaces here.
1063 destroySavedSurfaces();
1064
1065 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
1066 final WindowState win = allAppWindows.get(winNdx);
1067 if (win.mHasSurface && !resizingWindows.contains(win)) {
1068 if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
1069 resizingWindows.add(win);
1070
1071 // If we are not drag resizing, force recreating of a new surface so updating
1072 // the content and positioning that surface will be in sync.
1073 //
1074 // As we use this flag as a hint to freeze surface boundary updates,
1075 // we'd like to only apply this to TYPE_BASE_APPLICATION,
1076 // windows of TYPE_APPLICATION like dialogs, could appear
1077 // to not be drag resizing while they resize, but we'd
1078 // still like to manipulate their frame to update crop, etc...
1079 //
1080 // Anyway we don't need to synchronize position and content updates for these
1081 // windows since they aren't at the base layer and could be moved around anyway.
1082 if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
1083 !mTask.mStack.getBoundsAnimating() && !win.isGoneForLayoutLw() &&
1084 !mTask.inPinnedWorkspace()) {
1085 win.setResizedWhileNotDragResizing(true);
1086 }
1087 }
1088 if (win.isGoneForLayoutLw()) {
1089 win.mResizedWhileGone = true;
1090 }
1091 }
1092 }
1093
1094 void moveWindows() {
1095 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
1096 final WindowState win = allAppWindows.get(winNdx);
1097 if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
1098 win.mMovedByResize = true;
1099 }
1100 }
1101
1102 void notifyMovedInStack() {
1103 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
1104 final WindowState win = allAppWindows.get(winNdx);
1105 win.notifyMovedInStack();
1106 }
1107 }
1108
1109 void resetDragResizingChangeReported() {
1110 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
1111 final WindowState win = allAppWindows.get(winNdx);
1112 win.resetDragResizingChangeReported();
1113 }
1114 }
1115
1116 void detachDisplay() {
1117 boolean doAnotherLayoutPass = false;
1118 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
1119 // We are in the middle of changing the state of displays/stacks/tasks. We need
1120 // to finish that, before we let layout interfere with it.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001121 mService.removeWindowLocked(allAppWindows.get(winNdx));
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001122 doAnotherLayoutPass = true;
1123 }
1124 if (doAnotherLayoutPass) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001125 mService.mWindowPlacerLocked.requestTraversal();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001126 }
1127 }
1128
1129 void forceWindowsScaleableInTransaction(boolean force) {
1130 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
1131 final WindowStateAnimator winAnimator = allAppWindows.get(winNdx).mWinAnimator;
1132 if (winAnimator == null || !winAnimator.hasSurface()) {
1133 continue;
1134 }
1135 winAnimator.mSurfaceController.forceScaleableInTransaction(force);
1136 }
1137 }
1138
1139 boolean isAnimating() {
1140 for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
1141 final WindowStateAnimator winAnimator = allAppWindows.get(winNdx).mWinAnimator;
1142 if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
1143 return true;
1144 }
1145 }
1146 return false;
1147 }
1148
1149 void setAppLayoutChanges(int changes, String reason, int displayId) {
1150 final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
1151 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
1152 if (displayId == allAppWindows.get(i).getDisplayId()) {
1153 windowAnimator.setPendingLayoutChanges(displayId, changes);
1154 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001155 mService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001156 reason, windowAnimator.getPendingLayoutChanges(displayId));
1157 }
1158 break;
1159 }
1160 }
1161 }
1162
1163 void removeReplacedWindowIfNeeded(WindowState replacement) {
1164 for (int i = allAppWindows.size() - 1; i >= 0; i--) {
1165 final WindowState win = allAppWindows.get(i);
1166 if (win.mWillReplaceWindow && win.mReplacingWindow == replacement
1167 && replacement.hasDrawnLw()) {
1168 replacement.mSkipEnterAnimationForSeamlessReplacement = false;
1169 win.removeReplacedWindow();
1170 }
1171 }
1172 }
1173
1174 void startFreezingScreen() {
1175 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
1176 + hidden + " freezing=" + mAppAnimator.freezingScreen);
1177 if (!hiddenRequested) {
1178 if (!mAppAnimator.freezingScreen) {
1179 mAppAnimator.freezingScreen = true;
1180 mAppAnimator.lastFreezeDuration = 0;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001181 mService.mAppsFreezingScreen++;
1182 if (mService.mAppsFreezingScreen == 1) {
1183 mService.startFreezingDisplayLocked(false, 0, 0);
1184 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1185 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001186 }
1187 }
1188 final int count = allAppWindows.size();
1189 for (int i = 0; i < count; i++) {
1190 final WindowState w = allAppWindows.get(i);
1191 w.mAppFreezing = true;
1192 }
1193 }
1194 }
1195
1196 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
1197 if (!mAppAnimator.freezingScreen) {
1198 return;
1199 }
1200 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
1201 final int count = allAppWindows.size();
1202 boolean unfrozeWindows = false;
1203 for (int i = 0; i < count; i++) {
1204 final WindowState w = allAppWindows.get(i);
1205 if (w.mAppFreezing) {
1206 w.mAppFreezing = false;
1207 if (w.mHasSurface && !w.mOrientationChanging
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001208 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001209 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
1210 w.mOrientationChanging = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001211 mService.mWindowPlacerLocked.mOrientationChangeComplete = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001212 }
1213 w.mLastFreezeDuration = 0;
1214 unfrozeWindows = true;
1215 w.setDisplayLayoutNeeded();
1216 }
1217 }
1218 if (force || unfrozeWindows) {
1219 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
1220 mAppAnimator.freezingScreen = false;
1221 mAppAnimator.lastFreezeDuration =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001222 (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime);
1223 mService.mAppsFreezingScreen--;
1224 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001225 }
1226 if (unfreezeSurfaceNow) {
1227 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001228 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001229 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001230 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001231 }
1232 }
1233
1234 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001235 final AppWindowToken fromToken = mService.findAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001236 if (fromToken == null) {
1237 return false;
1238 }
1239
1240 final WindowState tStartingWindow = fromToken.startingWindow;
1241 if (tStartingWindow != null && fromToken.startingView != null) {
1242 // In this case, the starting icon has already been displayed, so start
1243 // letting windows get shown immediately without any more transitions.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001244 mService.mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001245
1246 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1247 + " from " + fromToken + " to " + this);
1248
1249 final long origId = Binder.clearCallingIdentity();
1250
1251 // Transfer the starting window over to the new token.
1252 startingData = fromToken.startingData;
1253 startingView = fromToken.startingView;
1254 startingDisplayed = fromToken.startingDisplayed;
1255 fromToken.startingDisplayed = false;
1256 startingWindow = tStartingWindow;
1257 reportedVisible = fromToken.reportedVisible;
1258 fromToken.startingData = null;
1259 fromToken.startingView = null;
1260 fromToken.startingWindow = null;
1261 fromToken.startingMoved = true;
1262 tStartingWindow.mToken = this;
1263 tStartingWindow.mRootToken = this;
1264 tStartingWindow.mAppToken = this;
1265
1266 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1267 "Removing starting window: " + tStartingWindow);
1268 tStartingWindow.getWindowList().remove(tStartingWindow);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001269 mService.mWindowsChanged = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001270 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1271 "Removing starting " + tStartingWindow + " from " + fromToken);
1272 fromToken.removeWindow(tStartingWindow);
1273 fromToken.allAppWindows.remove(tStartingWindow);
1274 addWindowToList(tStartingWindow);
1275
1276 // Propagate other interesting state between the tokens. If the old token is displayed,
1277 // we should immediately force the new one to be displayed. If it is animating, we need
1278 // to move that animation to the new one.
1279 if (fromToken.allDrawn) {
1280 allDrawn = true;
1281 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1282 }
1283 if (fromToken.firstWindowDrawn) {
1284 firstWindowDrawn = true;
1285 }
1286 if (!fromToken.hidden) {
1287 hidden = false;
1288 hiddenRequested = false;
1289 }
1290 if (clientHidden != fromToken.clientHidden) {
1291 clientHidden = fromToken.clientHidden;
1292 sendAppVisibilityToClients();
1293 }
1294 fromToken.mAppAnimator.transferCurrentAnimation(
1295 mAppAnimator, tStartingWindow.mWinAnimator);
1296
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001297 mService.updateFocusedWindowLocked(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001298 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001299 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1300 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001301 Binder.restoreCallingIdentity(origId);
1302 return true;
1303 } else if (fromToken.startingData != null) {
1304 // The previous app was getting ready to show a
1305 // starting window, but hasn't yet done so. Steal it!
1306 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1307 "Moving pending starting from " + fromToken + " to " + this);
1308 startingData = fromToken.startingData;
1309 fromToken.startingData = null;
1310 fromToken.startingMoved = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001311 final Message m = mService.mH.obtainMessage(H.ADD_STARTING, this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001312 // Note: we really want to do sendMessageAtFrontOfQueue() because we want to process the
1313 // message ASAP, before any other queued messages.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001314 mService.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001315 return true;
1316 }
1317
1318 final AppWindowAnimator tAppAnimator = fromToken.mAppAnimator;
1319 final AppWindowAnimator wAppAnimator = mAppAnimator;
1320 if (tAppAnimator.thumbnail != null) {
1321 // The old token is animating with a thumbnail, transfer that to the new token.
1322 if (wAppAnimator.thumbnail != null) {
1323 wAppAnimator.thumbnail.destroy();
1324 }
1325 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
1326 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
1327 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
1328 tAppAnimator.thumbnail = null;
1329 }
1330 return false;
1331 }
1332
1333 int getWindowsCount() {
1334 return allAppWindows.size();
1335 }
1336
1337 void setAllAppWinAnimators() {
1338 final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
1339 allAppWinAnimators.clear();
1340
1341 final int windowsCount = allAppWindows.size();
1342 for (int j = 0; j < windowsCount; j++) {
1343 allAppWinAnimators.add(allAppWindows.get(j).mWinAnimator);
1344 }
1345 }
1346
1347 /** Returns true if the app token windows list is empty. */
1348 @Override
1349 boolean isEmpty() {
1350 return allAppWindows.isEmpty();
1351 }
1352
Craig Mautnerdbb79912012-03-01 18:59:14 -08001353 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001354 AppWindowToken asAppWindowToken() {
1355 // I am an app window token!
1356 return this;
1357 }
1358
1359 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001360 void dump(PrintWriter pw, String prefix) {
1361 super.dump(pw, prefix);
1362 if (appToken != null) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001363 pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001364 }
1365 if (allAppWindows.size() > 0) {
1366 pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
1367 }
Craig Mautner83162a92015-01-26 14:43:30 -08001368 pw.print(prefix); pw.print("task="); pw.println(mTask);
1369 pw.print(prefix); pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001370 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
1371 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
1372 pw.print(" clientHidden="); pw.print(clientHidden);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07001373 pw.print(" reportedDrawn="); pw.print(reportedDrawn);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001374 pw.print(" reportedVisible="); pw.println(reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07001375 if (paused) {
1376 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001377 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001378 if (mAppStopped) {
1379 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
1380 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001381 if (numInterestingWindows != 0 || numDrawnWindows != 0
Craig Mautner6fbda632012-07-03 09:26:39 -07001382 || allDrawn || mAppAnimator.allDrawn) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001383 pw.print(prefix); pw.print("numInterestingWindows=");
1384 pw.print(numInterestingWindows);
1385 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
1386 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07001387 pw.print(" allDrawn="); pw.print(allDrawn);
1388 pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
1389 pw.println(")");
1390 }
1391 if (inPendingTransaction) {
1392 pw.print(prefix); pw.print("inPendingTransaction=");
1393 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001394 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08001395 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001396 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
1397 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08001398 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08001399 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001400 }
1401 if (startingWindow != null || startingView != null
1402 || startingDisplayed || startingMoved) {
1403 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
1404 pw.print(" startingView="); pw.print(startingView);
1405 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001406 pw.print(" startingMoved="); pw.println(startingMoved);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001407 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01001408 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001409 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001410 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08001411 }
1412 if (mPendingRelaunchCount != 0) {
1413 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01001414 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001415 }
1416
1417 @Override
1418 public String toString() {
1419 if (stringName == null) {
1420 StringBuilder sb = new StringBuilder();
1421 sb.append("AppWindowToken{");
1422 sb.append(Integer.toHexString(System.identityHashCode(this)));
1423 sb.append(" token="); sb.append(token); sb.append('}');
1424 stringName = sb.toString();
1425 }
1426 return stringName;
1427 }
Jeff Browne9bdb312012-04-05 15:30:10 -07001428}