blob: d3dab440c44af68db107c4e9bbd29ed0238ecad9 [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() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700501 for (int i = windows.size() - 1; i >= 0; i--) {
502 final WindowState win = windows.get(i);
Chong Zhange05bcb12016-07-26 17:47:29 -0700503 // We don't want to clear it out for windows that get replaced, because the
504 // animation depends on the flag to remove the replaced window.
505 //
506 // We also don't clear the mAnimatingExit flag for windows which have the
507 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
508 // by the client. We should let animation proceed and not clear this flag or
509 // they won't eventually be removed by WindowStateAnimator#finishExit.
510 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
511 win.mAnimatingExit = false;
512 // 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.
519 win.mWinAnimator.mAnimating = false;
Wale Ogunwale3c0d44e2016-08-11 09:34:45 -0700520
521 if (win.mDestroying) {
522 win.mDestroying = false;
Chong Zhang12d266f2016-08-11 16:27:43 -0700523 mService.mDestroySurface.remove(win);
Wale Ogunwale3c0d44e2016-08-11 09:34:45 -0700524 }
Chong Zhange05bcb12016-07-26 17:47:29 -0700525 }
526 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700527 requestUpdateWallpaperIfNeeded();
Chong Zhange05bcb12016-07-26 17:47:29 -0700528 }
529
Robert Carre12aece2016-02-02 22:43:27 -0800530 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700531 destroySurfaces(false /*cleanupOnResume*/);
532 }
533
534 /**
535 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
536 * the client has finished with them.
537 *
538 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
539 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
540 * others so that they are ready to be reused. If set to false (common case), destroy all
541 * surfaces that's eligible, if the app is already stopped.
542 */
543
544 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700545 final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) windows.clone();
Robert Carre12aece2016-02-02 22:43:27 -0800546 final DisplayContentList displayList = new DisplayContentList();
547 for (int i = allWindows.size() - 1; i >= 0; i--) {
548 final WindowState win = allWindows.get(i);
Chong Zhangeb665572016-05-09 18:28:27 -0700549
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700550 if (!(mAppStopped || win.mWindowRemovalAllowed || cleanupOnResume)) {
Robert Carre12aece2016-02-02 22:43:27 -0800551 continue;
552 }
553
Chong Zhangeb665572016-05-09 18:28:27 -0700554 win.mWinAnimator.destroyPreservedSurfaceLocked();
555
556 if (!win.mDestroying) {
Chong Zhang5471e902016-02-12 15:34:10 -0800557 continue;
Robert Carre12aece2016-02-02 22:43:27 -0800558 }
559
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800560 if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + win
561 + " destroySurfaces: mAppStopped=" + mAppStopped
562 + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed
563 + " win.mRemoveOnExit=" + win.mRemoveOnExit);
564
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700565 if (!cleanupOnResume || win.mRemoveOnExit) {
566 win.destroyOrSaveSurface();
567 }
Robert Carre12aece2016-02-02 22:43:27 -0800568 if (win.mRemoveOnExit) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700569 win.remove();
Robert Carre12aece2016-02-02 22:43:27 -0800570 }
571 final DisplayContent displayContent = win.getDisplayContent();
572 if (displayContent != null && !displayList.contains(displayContent)) {
573 displayList.add(displayContent);
574 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700575 if (cleanupOnResume) {
576 win.requestUpdateWallpaperIfNeeded();
577 }
Robert Carre12aece2016-02-02 22:43:27 -0800578 win.mDestroying = false;
579 }
580 for (int i = 0; i < displayList.size(); i++) {
581 final DisplayContent displayContent = displayList.get(i);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700582 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Robert Carre12aece2016-02-02 22:43:27 -0800583 displayContent.layoutNeeded = true;
584 }
585 }
586
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800587 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700588 * Notify that the app is now resumed, and it was not stopped before, perform a clean
589 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800590 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700591 void notifyAppResumed(boolean wasStopped) {
592 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this);
593 mAppStopped = false;
594 if (!wasStopped) {
595 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800596 }
Robert Carre12aece2016-02-02 22:43:27 -0800597 }
598
Chong Zhangbef461f2015-10-27 11:38:24 -0700599 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700600 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
601 * keeping alive in case they were still being used.
602 */
603 void notifyAppStopped() {
604 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
605 mAppStopped = true;
606 destroySurfaces();
607 // Remove any starting window that was added for this app if they are still around.
608 mTask.mService.scheduleRemoveStartingWindowLocked(this);
609 }
610
611 /**
Chong Zhangbef461f2015-10-27 11:38:24 -0700612 * Checks whether we should save surfaces for this app.
613 *
614 * @return true if the surfaces should be saved, false otherwise.
615 */
616 boolean shouldSaveSurface() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800617 // We want to save surface if the app's windows are "allDrawn".
618 // (If we started entering animation early with saved surfaces, allDrawn
619 // should have been restored to true. So we'll save again in that case
620 // even if app didn't actually finish drawing.)
621 return allDrawn;
Robert Carr13f7be9e2015-12-02 18:39:45 -0800622 }
623
Chong Zhang92147042016-05-09 12:47:11 -0700624 boolean canRestoreSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700625 for (int i = windows.size() -1; i >= 0; i--) {
626 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700627 if (w.canRestoreSurface()) {
Robert Carr13f7be9e2015-12-02 18:39:45 -0800628 return true;
629 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700630 }
631 return false;
632 }
633
Chong Zhang92147042016-05-09 12:47:11 -0700634 void clearVisibleBeforeClientHidden() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700635 for (int i = windows.size() - 1; i >= 0; i--) {
636 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700637 w.clearVisibleBeforeClientHidden();
638 }
639 }
640
Chong Zhang8e4bda92016-05-04 15:08:18 -0700641 /**
642 * Whether the app has some window that is invisible in layout, but
643 * animating with saved surface.
644 */
645 boolean isAnimatingInvisibleWithSavedSurface() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700646 for (int i = windows.size() - 1; i >= 0; i--) {
647 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700648 if (w.isAnimatingInvisibleWithSavedSurface()) {
649 return true;
650 }
651 }
652 return false;
653 }
654
655 /**
656 * Hide all window surfaces that's still invisible in layout but animating
657 * with a saved surface, and mark them destroying.
658 */
659 void stopUsingSavedSurfaceLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700660 for (int i = windows.size() - 1; i >= 0; i--) {
661 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700662 if (w.isAnimatingInvisibleWithSavedSurface()) {
663 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
664 "stopUsingSavedSurfaceLocked: " + w);
665 w.clearAnimatingWithSavedSurface();
666 w.mDestroying = true;
667 w.mWinAnimator.hide("stopUsingSavedSurfaceLocked");
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700668 mService.mWallpaperControllerLocked.hideWallpapers(w);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700669 }
670 }
671 destroySurfaces();
672 }
673
Chong Zhangf58631a2016-05-24 16:02:10 -0700674 void markSavedSurfaceExiting() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700675 for (int i = windows.size() - 1; i >= 0; i--) {
676 final WindowState w = windows.get(i);
Chong Zhangf58631a2016-05-24 16:02:10 -0700677 if (w.isAnimatingInvisibleWithSavedSurface()) {
678 w.mAnimatingExit = true;
679 w.mWinAnimator.mAnimating = true;
680 }
681 }
682 }
683
Chong Zhangbef461f2015-10-27 11:38:24 -0700684 void restoreSavedSurfaces() {
Chong Zhang92147042016-05-09 12:47:11 -0700685 if (!canRestoreSurfaces()) {
686 clearVisibleBeforeClientHidden();
Chong Zhangbef461f2015-10-27 11:38:24 -0700687 return;
688 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800689 // Check if we have enough drawn windows to mark allDrawn= true.
690 int numInteresting = 0;
691 int numDrawn = 0;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700692 for (int i = windows.size() - 1; i >= 0; i--) {
693 WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700694 if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800695 && (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
696 numInteresting++;
Chong Zhang92147042016-05-09 12:47:11 -0700697 if (w.hasSavedSurface()) {
698 w.restoreSavedSurface();
699 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800700 if (w.isDrawnLw()) {
701 numDrawn++;
702 }
703 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700704 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800705
Chong Zhang92147042016-05-09 12:47:11 -0700706 if (!allDrawn) {
707 allDrawn = (numInteresting > 0) && (numInteresting == numDrawn);
708 if (allDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700709 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Chong Zhang92147042016-05-09 12:47:11 -0700710 }
711 }
712 clearVisibleBeforeClientHidden();
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800713
714 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
Wale Ogunwale455fac52016-07-21 07:24:49 -0700715 "restoreSavedSurfaces: " + this + " allDrawn=" + allDrawn
Chong Zhang92147042016-05-09 12:47:11 -0700716 + " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
Chong Zhangbef461f2015-10-27 11:38:24 -0700717 }
718
719 void destroySavedSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700720 for (int i = windows.size() - 1; i >= 0; i--) {
721 WindowState win = windows.get(i);
Robert Carr13f7be9e2015-12-02 18:39:45 -0800722 win.destroySavedSurface();
Chong Zhangbef461f2015-10-27 11:38:24 -0700723 }
Chong Zhang92147042016-05-09 12:47:11 -0700724 }
725
726 void clearAllDrawn() {
727 allDrawn = false;
728 deferClearAllDrawn = false;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700729 allDrawnExcludingSaved = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700730 }
731
Wale Ogunwale98e70d02014-11-10 12:12:27 -0800732 @Override
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700733 void removeWindow(WindowState win) {
734 super.removeWindow(win);
735
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700736 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700737 if (startingWindow == win) {
738 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700739 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700740 } else if (windows.size() == 0 && startingData != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700741 // If this is the last window and we had requested a starting transition window,
742 // well there is no point now.
743 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
744 startingData = null;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700745 } else if (windows.size() == 1 && startingView != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700746 // If this is the last window except for a starting transition window,
747 // we need to get rid of the starting transition.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700748 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700749 }
750 }
751
Chong Zhang112eb8c2015-11-02 11:17:00 -0800752 void removeAllDeadWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700753 for (int winNdx = windows.size() - 1; winNdx >= 0;
754 // WindowState#removeIfPossible() at bottom of loop may remove multiple entries from
755 // windows if the window to be removed has child windows. It also may
756 // not remove any windows from windows at all if win is exiting and
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700757 // currently animating away. This ensures that winNdx is monotonically decreasing
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700758 // and never beyond windows bounds.
759 winNdx = Math.min(winNdx - 1, windows.size() - 1)) {
760 WindowState win = windows.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800761 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700762 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
763 "removeAllDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800764 // Set mDestroying, we don't want any animation or delayed removal here.
765 win.mDestroying = true;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700766 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800767 }
768 }
769 }
770
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700771 boolean hasWindowsAlive() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700772 for (int i = windows.size() - 1; i >= 0; i--) {
773 if (!windows.get(i).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700774 return true;
775 }
776 }
777 return false;
778 }
779
Robert Carra1eb4392015-12-10 12:43:51 -0800780 void setReplacingWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700781 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
782 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800783
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700784 for (int i = windows.size() - 1; i >= 0; i--) {
785 final WindowState w = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800786 w.setReplacing(animate);
787 }
788 if (animate) {
789 // Set-up dummy animation so we can start treating windows associated with this
790 // token like they are in transition before the new app window is ready for us to
791 // run the real transition animation.
792 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
793 "setReplacingWindow() Setting dummy animation on: " + this);
794 mAppAnimator.setDummyAnimation();
795 }
796 }
797
Robert Carr23fa16b2016-01-13 13:19:58 -0800798 void setReplacingChildren() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700799 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800800 + " with replacing child windows.");
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700801 for (int i = windows.size() - 1; i >= 0; i--) {
802 final WindowState w = windows.get(i);
Robert Carrd1a010f2016-04-07 22:36:22 -0700803 if (w.shouldBeReplacedWithChildren()) {
Robert Carr23fa16b2016-01-13 13:19:58 -0800804 w.setReplacing(false /* animate */);
805 }
806 }
807 }
808
Chong Zhangf596cd52016-01-05 13:42:44 -0800809 void resetReplacingWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700810 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
811 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800812
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700813 for (int i = windows.size() - 1; i >= 0; i--) {
814 final WindowState w = windows.get(i);
Chong Zhangf596cd52016-01-05 13:42:44 -0800815 w.resetReplacing();
816 }
817 }
818
Chong Zhang4d7369a2016-04-25 16:09:14 -0700819 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700820 for (int i = windows.size() - 1; i >= 0; i--) {
821 final WindowState w = windows.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -0700822 w.requestUpdateWallpaperIfNeeded();
823 }
824 }
825
Chong Zhangd78ddb42016-03-02 17:01:14 -0800826 boolean isRelaunching() {
827 return mPendingRelaunchCount > 0;
828 }
829
830 void startRelaunching() {
831 if (canFreezeBounds()) {
832 freezeBounds();
833 }
834 mPendingRelaunchCount++;
835 }
836
837 void finishRelaunching() {
838 if (canFreezeBounds()) {
839 unfreezeBounds();
840 }
841 if (mPendingRelaunchCount > 0) {
842 mPendingRelaunchCount--;
843 }
844 }
845
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700846 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700847 if (mPendingRelaunchCount == 0) {
848 return;
849 }
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700850 if (canFreezeBounds()) {
851 unfreezeBounds();
852 }
853 mPendingRelaunchCount = 0;
854 }
855
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700856 @Override
Robert Carra1eb4392015-12-10 12:43:51 -0800857 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700858 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700859
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700860 for (int i = windows.size() - 1; i >= 0; i--) {
861 final WindowState candidate = windows.get(i);
862 if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null
863 && candidate.getWindowTag().toString().equals(w.getWindowTag().toString())) {
864
Robert Carra1eb4392015-12-10 12:43:51 -0800865 candidate.mReplacingWindow = w;
Robert Carrb439a632016-04-07 22:52:10 -0700866 w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow;
Chong Zhangf596cd52016-01-05 13:42:44 -0800867 // if we got a replacement window, reset the timeout to give drawing more time
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700868 mService.scheduleReplacingWindowTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -0800869 }
870 }
Robert Carra1eb4392015-12-10 12:43:51 -0800871 }
872
873 boolean waitingForReplacement() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700874 for (int i = windows.size() - 1; i >= 0; i--) {
875 WindowState candidate = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800876 if (candidate.mWillReplaceWindow) {
877 return true;
878 }
879 }
880 return false;
881 }
882
Chong Zhangf596cd52016-01-05 13:42:44 -0800883 void clearTimedoutReplacesLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700884 for (int i = windows.size() - 1; i >= 0;
885 // WindowState#remove() at bottom of loop may remove multiple entries from windows if
886 // the window to be removed has child windows. It also may not remove any windows from
887 // windows at all if win is exiting and currently animating away. This ensures that
888 // winNdx is monotonically decreasing and never beyond windows bounds.
889 i = Math.min(i - 1, windows.size() - 1)) {
890 final WindowState candidate = windows.get(i);
891 if (!candidate.mWillReplaceWindow) {
Robert Carra1eb4392015-12-10 12:43:51 -0800892 continue;
893 }
894 candidate.mWillReplaceWindow = false;
Robert Carrb439a632016-04-07 22:52:10 -0700895 if (candidate.mReplacingWindow != null) {
896 candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false;
897 }
Chong Zhangf596cd52016-01-05 13:42:44 -0800898 // Since the window already timed out, remove it immediately now.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700899 // Use WindowState#remove() instead of WindowState#removeIfPossible(), as the latter
Chong Zhangf596cd52016-01-05 13:42:44 -0800900 // delays removal on certain conditions, which will leave the stale window in the
901 // stack and marked mWillReplaceWindow=false, so the window will never be removed.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700902 candidate.remove();
Robert Carra1eb4392015-12-10 12:43:51 -0800903 }
904 }
905
Chong Zhangd78ddb42016-03-02 17:01:14 -0800906 private boolean canFreezeBounds() {
907 // For freeform windows, we can't freeze the bounds at the moment because this would make
908 // the resizing unresponsive.
909 return mTask != null && !mTask.inFreeformWorkspace();
910 }
911
Jorim Jaggi0429f352015-12-22 16:29:16 +0100912 /**
913 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
914 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
915 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
916 * with a queue.
917 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800918 private void freezeBounds() {
Jorim Jaggi0429f352015-12-22 16:29:16 +0100919 mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700920
921 if (mTask.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
922 // We didn't call prepareFreezingBounds on the task, so use the current value.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700923 final Configuration config = new Configuration(mService.mCurConfiguration);
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700924 config.updateFrom(mTask.mOverrideConfig);
925 mFrozenMergedConfig.offer(config);
926 } else {
927 mFrozenMergedConfig.offer(new Configuration(mTask.mPreparedFrozenMergedConfig));
928 }
929 mTask.mPreparedFrozenMergedConfig.setToDefaults();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100930 }
931
932 /**
933 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
934 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800935 private void unfreezeBounds() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700936 if (!mFrozenBounds.isEmpty()) {
937 mFrozenBounds.remove();
938 }
939 if (!mFrozenMergedConfig.isEmpty()) {
940 mFrozenMergedConfig.remove();
941 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700942 for (int i = windows.size() - 1; i >= 0; i--) {
943 final WindowState win = windows.get(i);
Jorim Jaggi69abc192016-02-04 19:34:00 -0800944 if (!win.mHasSurface) {
945 continue;
946 }
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100947 win.mLayoutNeeded = true;
948 win.setDisplayLayoutNeeded();
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700949 if (!mService.mResizingWindows.contains(win)) {
950 mService.mResizingWindows.add(win);
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100951 }
952 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700953 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100954 }
955
Robert Carr91b228092016-06-28 17:32:37 -0700956 void addSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
957 mSurfaceViewBackgrounds.add(background);
958 }
959
960 void removeSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
961 mSurfaceViewBackgrounds.remove(background);
962 updateSurfaceViewBackgroundVisibilities();
963 }
964
965 // We use DimLayers behind SurfaceViews to prevent holes while resizing and creating.
966 // However, we need to ensure one SurfaceView doesn't cover another when they are both placed
967 // below the main app window (as traditionally a SurfaceView which is never drawn
968 // to is totally translucent). So we look at all our SurfaceView backgrounds and only enable
969 // the background for the SurfaceView with lowest Z order
970 void updateSurfaceViewBackgroundVisibilities() {
971 WindowSurfaceController.SurfaceControlWithBackground bottom = null;
972 int bottomLayer = Integer.MAX_VALUE;
973 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
974 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
975 if (sc.mVisible && sc.mLayer < bottomLayer) {
976 bottomLayer = sc.mLayer;
977 bottom = sc;
978 }
979 }
980 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
981 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
982 sc.updateBackgroundVisibility(sc != bottom);
983 }
984 }
985
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700986 void resetJustMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700987 for (int i = windows.size() - 1; i >= 0; i--) {
988 windows.get(i).resetJustMovedInStack();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700989 }
990 }
991
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700992 void setWaitingForDrawnIfResizingChanged() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700993 for (int i = windows.size() - 1; i >= 0; --i) {
994 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700995 if (win.isDragResizeChanged()) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700996 mService.mWaitingForDrawn.add(win);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700997 }
998 }
999 }
1000
1001 void resizeWindows() {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001002 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001003 // Some windows won't go through the resizing process, if they don't have a surface, so
1004 // destroy all saved surfaces here.
1005 destroySavedSurfaces();
1006
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001007 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1008 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001009 if (win.mHasSurface && !resizingWindows.contains(win)) {
1010 if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
1011 resizingWindows.add(win);
1012
1013 // If we are not drag resizing, force recreating of a new surface so updating
1014 // the content and positioning that surface will be in sync.
1015 //
1016 // As we use this flag as a hint to freeze surface boundary updates,
1017 // we'd like to only apply this to TYPE_BASE_APPLICATION,
1018 // windows of TYPE_APPLICATION like dialogs, could appear
1019 // to not be drag resizing while they resize, but we'd
1020 // still like to manipulate their frame to update crop, etc...
1021 //
1022 // Anyway we don't need to synchronize position and content updates for these
1023 // windows since they aren't at the base layer and could be moved around anyway.
1024 if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
1025 !mTask.mStack.getBoundsAnimating() && !win.isGoneForLayoutLw() &&
1026 !mTask.inPinnedWorkspace()) {
1027 win.setResizedWhileNotDragResizing(true);
1028 }
1029 }
1030 if (win.isGoneForLayoutLw()) {
1031 win.mResizedWhileGone = true;
1032 }
1033 }
1034 }
1035
1036 void moveWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001037 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1038 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001039 if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
1040 win.mMovedByResize = true;
1041 }
1042 }
1043
1044 void notifyMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001045 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1046 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001047 win.notifyMovedInStack();
1048 }
1049 }
1050
1051 void resetDragResizingChangeReported() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001052 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1053 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001054 win.resetDragResizingChangeReported();
1055 }
1056 }
1057
1058 void detachDisplay() {
1059 boolean doAnotherLayoutPass = false;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001060 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001061 // We are in the middle of changing the state of displays/stacks/tasks. We need
1062 // to finish that, before we let layout interfere with it.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001063 windows.get(winNdx).removeIfPossible();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001064 doAnotherLayoutPass = true;
1065 }
1066 if (doAnotherLayoutPass) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001067 mService.mWindowPlacerLocked.requestTraversal();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001068 }
1069 }
1070
1071 void forceWindowsScaleableInTransaction(boolean force) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001072 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1073 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001074 if (winAnimator == null || !winAnimator.hasSurface()) {
1075 continue;
1076 }
1077 winAnimator.mSurfaceController.forceScaleableInTransaction(force);
1078 }
1079 }
1080
1081 boolean isAnimating() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001082 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1083 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001084 if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
1085 return true;
1086 }
1087 }
1088 return false;
1089 }
1090
1091 void setAppLayoutChanges(int changes, String reason, int displayId) {
1092 final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001093 for (int i = windows.size() - 1; i >= 0; i--) {
1094 if (displayId == windows.get(i).getDisplayId()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001095 windowAnimator.setPendingLayoutChanges(displayId, changes);
1096 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001097 mService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001098 reason, windowAnimator.getPendingLayoutChanges(displayId));
1099 }
1100 break;
1101 }
1102 }
1103 }
1104
1105 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001106 for (int i = windows.size() - 1; i >= 0; i--) {
1107 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001108 if (win.mWillReplaceWindow && win.mReplacingWindow == replacement
1109 && replacement.hasDrawnLw()) {
1110 replacement.mSkipEnterAnimationForSeamlessReplacement = false;
1111 win.removeReplacedWindow();
1112 }
1113 }
1114 }
1115
1116 void startFreezingScreen() {
1117 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
1118 + hidden + " freezing=" + mAppAnimator.freezingScreen);
1119 if (!hiddenRequested) {
1120 if (!mAppAnimator.freezingScreen) {
1121 mAppAnimator.freezingScreen = true;
1122 mAppAnimator.lastFreezeDuration = 0;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001123 mService.mAppsFreezingScreen++;
1124 if (mService.mAppsFreezingScreen == 1) {
1125 mService.startFreezingDisplayLocked(false, 0, 0);
1126 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1127 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001128 }
1129 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001130 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001131 for (int i = 0; i < count; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001132 final WindowState w = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001133 w.mAppFreezing = true;
1134 }
1135 }
1136 }
1137
1138 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
1139 if (!mAppAnimator.freezingScreen) {
1140 return;
1141 }
1142 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001143 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001144 boolean unfrozeWindows = false;
1145 for (int i = 0; i < count; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001146 final WindowState w = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001147 if (w.mAppFreezing) {
1148 w.mAppFreezing = false;
1149 if (w.mHasSurface && !w.mOrientationChanging
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001150 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001151 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
1152 w.mOrientationChanging = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001153 mService.mWindowPlacerLocked.mOrientationChangeComplete = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001154 }
1155 w.mLastFreezeDuration = 0;
1156 unfrozeWindows = true;
1157 w.setDisplayLayoutNeeded();
1158 }
1159 }
1160 if (force || unfrozeWindows) {
1161 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
1162 mAppAnimator.freezingScreen = false;
1163 mAppAnimator.lastFreezeDuration =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001164 (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime);
1165 mService.mAppsFreezingScreen--;
1166 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001167 }
1168 if (unfreezeSurfaceNow) {
1169 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001170 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001171 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001172 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001173 }
1174 }
1175
1176 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001177 final AppWindowToken fromToken = mService.findAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001178 if (fromToken == null) {
1179 return false;
1180 }
1181
1182 final WindowState tStartingWindow = fromToken.startingWindow;
1183 if (tStartingWindow != null && fromToken.startingView != null) {
1184 // In this case, the starting icon has already been displayed, so start
1185 // letting windows get shown immediately without any more transitions.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001186 mService.mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001187
1188 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1189 + " from " + fromToken + " to " + this);
1190
1191 final long origId = Binder.clearCallingIdentity();
1192
1193 // Transfer the starting window over to the new token.
1194 startingData = fromToken.startingData;
1195 startingView = fromToken.startingView;
1196 startingDisplayed = fromToken.startingDisplayed;
1197 fromToken.startingDisplayed = false;
1198 startingWindow = tStartingWindow;
1199 reportedVisible = fromToken.reportedVisible;
1200 fromToken.startingData = null;
1201 fromToken.startingView = null;
1202 fromToken.startingWindow = null;
1203 fromToken.startingMoved = true;
1204 tStartingWindow.mToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001205 tStartingWindow.mAppToken = this;
1206
1207 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1208 "Removing starting window: " + tStartingWindow);
1209 tStartingWindow.getWindowList().remove(tStartingWindow);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001210 mService.mWindowsChanged = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001211 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1212 "Removing starting " + tStartingWindow + " from " + fromToken);
1213 fromToken.removeWindow(tStartingWindow);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001214 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001215
1216 // Propagate other interesting state between the tokens. If the old token is displayed,
1217 // we should immediately force the new one to be displayed. If it is animating, we need
1218 // to move that animation to the new one.
1219 if (fromToken.allDrawn) {
1220 allDrawn = true;
1221 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1222 }
1223 if (fromToken.firstWindowDrawn) {
1224 firstWindowDrawn = true;
1225 }
1226 if (!fromToken.hidden) {
1227 hidden = false;
1228 hiddenRequested = false;
1229 }
1230 if (clientHidden != fromToken.clientHidden) {
1231 clientHidden = fromToken.clientHidden;
1232 sendAppVisibilityToClients();
1233 }
1234 fromToken.mAppAnimator.transferCurrentAnimation(
1235 mAppAnimator, tStartingWindow.mWinAnimator);
1236
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001237 mService.updateFocusedWindowLocked(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001238 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001239 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1240 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001241 Binder.restoreCallingIdentity(origId);
1242 return true;
1243 } else if (fromToken.startingData != null) {
1244 // The previous app was getting ready to show a
1245 // starting window, but hasn't yet done so. Steal it!
1246 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1247 "Moving pending starting from " + fromToken + " to " + this);
1248 startingData = fromToken.startingData;
1249 fromToken.startingData = null;
1250 fromToken.startingMoved = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001251 final Message m = mService.mH.obtainMessage(H.ADD_STARTING, this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001252 // Note: we really want to do sendMessageAtFrontOfQueue() because we want to process the
1253 // message ASAP, before any other queued messages.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001254 mService.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001255 return true;
1256 }
1257
1258 final AppWindowAnimator tAppAnimator = fromToken.mAppAnimator;
1259 final AppWindowAnimator wAppAnimator = mAppAnimator;
1260 if (tAppAnimator.thumbnail != null) {
1261 // The old token is animating with a thumbnail, transfer that to the new token.
1262 if (wAppAnimator.thumbnail != null) {
1263 wAppAnimator.thumbnail.destroy();
1264 }
1265 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
1266 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
1267 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
1268 tAppAnimator.thumbnail = null;
1269 }
1270 return false;
1271 }
1272
1273 int getWindowsCount() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001274 return windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001275 }
1276
1277 void setAllAppWinAnimators() {
1278 final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
1279 allAppWinAnimators.clear();
1280
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001281 final int windowsCount = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001282 for (int j = 0; j < windowsCount; j++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001283 allAppWinAnimators.add(windows.get(j).mWinAnimator);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001284 }
1285 }
1286
Craig Mautnerdbb79912012-03-01 18:59:14 -08001287 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001288 AppWindowToken asAppWindowToken() {
1289 // I am an app window token!
1290 return this;
1291 }
1292
1293 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001294 void dump(PrintWriter pw, String prefix) {
1295 super.dump(pw, prefix);
1296 if (appToken != null) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001297 pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001298 }
Craig Mautner83162a92015-01-26 14:43:30 -08001299 pw.print(prefix); pw.print("task="); pw.println(mTask);
1300 pw.print(prefix); pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001301 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
1302 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
1303 pw.print(" clientHidden="); pw.print(clientHidden);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07001304 pw.print(" reportedDrawn="); pw.print(reportedDrawn);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001305 pw.print(" reportedVisible="); pw.println(reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07001306 if (paused) {
1307 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001308 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001309 if (mAppStopped) {
1310 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
1311 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001312 if (numInterestingWindows != 0 || numDrawnWindows != 0
Craig Mautner6fbda632012-07-03 09:26:39 -07001313 || allDrawn || mAppAnimator.allDrawn) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001314 pw.print(prefix); pw.print("numInterestingWindows=");
1315 pw.print(numInterestingWindows);
1316 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
1317 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07001318 pw.print(" allDrawn="); pw.print(allDrawn);
1319 pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
1320 pw.println(")");
1321 }
1322 if (inPendingTransaction) {
1323 pw.print(prefix); pw.print("inPendingTransaction=");
1324 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001325 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08001326 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001327 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
1328 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08001329 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08001330 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001331 }
1332 if (startingWindow != null || startingView != null
1333 || startingDisplayed || startingMoved) {
1334 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
1335 pw.print(" startingView="); pw.print(startingView);
1336 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001337 pw.print(" startingMoved="); pw.println(startingMoved);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001338 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01001339 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001340 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001341 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08001342 }
1343 if (mPendingRelaunchCount != 0) {
1344 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01001345 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001346 }
1347
1348 @Override
1349 public String toString() {
1350 if (stringName == null) {
1351 StringBuilder sb = new StringBuilder();
1352 sb.append("AppWindowToken{");
1353 sb.append(Integer.toHexString(System.identityHashCode(this)));
1354 sb.append(" token="); sb.append(token); sb.append('}');
1355 stringName = sb.toString();
1356 }
1357 return stringName;
1358 }
Jeff Browne9bdb312012-04-05 15:30:10 -07001359}