blob: c78e94bff793718ddc7c97f457bcb8f30fe6a424 [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;
520 }
521 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700522 requestUpdateWallpaperIfNeeded();
Chong Zhange05bcb12016-07-26 17:47:29 -0700523 }
524
Robert Carre12aece2016-02-02 22:43:27 -0800525 void destroySurfaces() {
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700526 destroySurfaces(false /*cleanupOnResume*/);
527 }
528
529 /**
530 * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure
531 * the client has finished with them.
532 *
533 * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If
534 * set to true, destroy only surfaces of removed windows, and clear relevant flags of the
535 * others so that they are ready to be reused. If set to false (common case), destroy all
536 * surfaces that's eligible, if the app is already stopped.
537 */
538
539 private void destroySurfaces(boolean cleanupOnResume) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700540 final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) windows.clone();
Robert Carre12aece2016-02-02 22:43:27 -0800541 final DisplayContentList displayList = new DisplayContentList();
542 for (int i = allWindows.size() - 1; i >= 0; i--) {
543 final WindowState win = allWindows.get(i);
Chong Zhangeb665572016-05-09 18:28:27 -0700544
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700545 if (!(mAppStopped || win.mWindowRemovalAllowed || cleanupOnResume)) {
Robert Carre12aece2016-02-02 22:43:27 -0800546 continue;
547 }
548
Chong Zhangeb665572016-05-09 18:28:27 -0700549 win.mWinAnimator.destroyPreservedSurfaceLocked();
550
551 if (!win.mDestroying) {
Chong Zhang5471e902016-02-12 15:34:10 -0800552 continue;
Robert Carre12aece2016-02-02 22:43:27 -0800553 }
554
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800555 if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + win
556 + " destroySurfaces: mAppStopped=" + mAppStopped
557 + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed
558 + " win.mRemoveOnExit=" + win.mRemoveOnExit);
559
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700560 if (!cleanupOnResume || win.mRemoveOnExit) {
561 win.destroyOrSaveSurface();
562 }
Robert Carre12aece2016-02-02 22:43:27 -0800563 if (win.mRemoveOnExit) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700564 win.remove();
Robert Carre12aece2016-02-02 22:43:27 -0800565 }
566 final DisplayContent displayContent = win.getDisplayContent();
567 if (displayContent != null && !displayList.contains(displayContent)) {
568 displayList.add(displayContent);
569 }
Chong Zhangec8299c2016-07-29 13:09:40 -0700570 if (cleanupOnResume) {
571 win.requestUpdateWallpaperIfNeeded();
572 }
Robert Carre12aece2016-02-02 22:43:27 -0800573 win.mDestroying = false;
574 }
575 for (int i = 0; i < displayList.size(); i++) {
576 final DisplayContent displayContent = displayList.get(i);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700577 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Robert Carre12aece2016-02-02 22:43:27 -0800578 displayContent.layoutNeeded = true;
579 }
580 }
581
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800582 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700583 * Notify that the app is now resumed, and it was not stopped before, perform a clean
584 * up of the surfaces
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800585 */
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700586 void notifyAppResumed(boolean wasStopped) {
587 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this);
588 mAppStopped = false;
589 if (!wasStopped) {
590 destroySurfaces(true /*cleanupOnResume*/);
Wale Ogunwale8d5a5422016-03-03 18:28:21 -0800591 }
Robert Carre12aece2016-02-02 22:43:27 -0800592 }
593
Chong Zhangbef461f2015-10-27 11:38:24 -0700594 /**
Chong Zhang45e6d2d2016-07-20 18:33:56 -0700595 * Notify that the app has stopped, and it is okay to destroy any surfaces which were
596 * keeping alive in case they were still being used.
597 */
598 void notifyAppStopped() {
599 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
600 mAppStopped = true;
601 destroySurfaces();
602 // Remove any starting window that was added for this app if they are still around.
603 mTask.mService.scheduleRemoveStartingWindowLocked(this);
604 }
605
606 /**
Chong Zhangbef461f2015-10-27 11:38:24 -0700607 * Checks whether we should save surfaces for this app.
608 *
609 * @return true if the surfaces should be saved, false otherwise.
610 */
611 boolean shouldSaveSurface() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800612 // We want to save surface if the app's windows are "allDrawn".
613 // (If we started entering animation early with saved surfaces, allDrawn
614 // should have been restored to true. So we'll save again in that case
615 // even if app didn't actually finish drawing.)
616 return allDrawn;
Robert Carr13f7be9e2015-12-02 18:39:45 -0800617 }
618
Chong Zhang92147042016-05-09 12:47:11 -0700619 boolean canRestoreSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700620 for (int i = windows.size() -1; i >= 0; i--) {
621 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700622 if (w.canRestoreSurface()) {
Robert Carr13f7be9e2015-12-02 18:39:45 -0800623 return true;
624 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700625 }
626 return false;
627 }
628
Chong Zhang92147042016-05-09 12:47:11 -0700629 void clearVisibleBeforeClientHidden() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700630 for (int i = windows.size() - 1; i >= 0; i--) {
631 final WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700632 w.clearVisibleBeforeClientHidden();
633 }
634 }
635
Chong Zhang8e4bda92016-05-04 15:08:18 -0700636 /**
637 * Whether the app has some window that is invisible in layout, but
638 * animating with saved surface.
639 */
640 boolean isAnimatingInvisibleWithSavedSurface() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700641 for (int i = windows.size() - 1; i >= 0; i--) {
642 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700643 if (w.isAnimatingInvisibleWithSavedSurface()) {
644 return true;
645 }
646 }
647 return false;
648 }
649
650 /**
651 * Hide all window surfaces that's still invisible in layout but animating
652 * with a saved surface, and mark them destroying.
653 */
654 void stopUsingSavedSurfaceLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700655 for (int i = windows.size() - 1; i >= 0; i--) {
656 final WindowState w = windows.get(i);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700657 if (w.isAnimatingInvisibleWithSavedSurface()) {
658 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
659 "stopUsingSavedSurfaceLocked: " + w);
660 w.clearAnimatingWithSavedSurface();
661 w.mDestroying = true;
662 w.mWinAnimator.hide("stopUsingSavedSurfaceLocked");
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700663 mService.mWallpaperControllerLocked.hideWallpapers(w);
Chong Zhang8e4bda92016-05-04 15:08:18 -0700664 }
665 }
666 destroySurfaces();
667 }
668
Chong Zhangf58631a2016-05-24 16:02:10 -0700669 void markSavedSurfaceExiting() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700670 for (int i = windows.size() - 1; i >= 0; i--) {
671 final WindowState w = windows.get(i);
Chong Zhangf58631a2016-05-24 16:02:10 -0700672 if (w.isAnimatingInvisibleWithSavedSurface()) {
673 w.mAnimatingExit = true;
674 w.mWinAnimator.mAnimating = true;
675 }
676 }
677 }
678
Chong Zhangbef461f2015-10-27 11:38:24 -0700679 void restoreSavedSurfaces() {
Chong Zhang92147042016-05-09 12:47:11 -0700680 if (!canRestoreSurfaces()) {
681 clearVisibleBeforeClientHidden();
Chong Zhangbef461f2015-10-27 11:38:24 -0700682 return;
683 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800684 // Check if we have enough drawn windows to mark allDrawn= true.
685 int numInteresting = 0;
686 int numDrawn = 0;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700687 for (int i = windows.size() - 1; i >= 0; i--) {
688 WindowState w = windows.get(i);
Chong Zhang92147042016-05-09 12:47:11 -0700689 if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800690 && (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
691 numInteresting++;
Chong Zhang92147042016-05-09 12:47:11 -0700692 if (w.hasSavedSurface()) {
693 w.restoreSavedSurface();
694 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800695 if (w.isDrawnLw()) {
696 numDrawn++;
697 }
698 }
Chong Zhangbef461f2015-10-27 11:38:24 -0700699 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800700
Chong Zhang92147042016-05-09 12:47:11 -0700701 if (!allDrawn) {
702 allDrawn = (numInteresting > 0) && (numInteresting == numDrawn);
703 if (allDrawn) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700704 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
Chong Zhang92147042016-05-09 12:47:11 -0700705 }
706 }
707 clearVisibleBeforeClientHidden();
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800708
709 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
Wale Ogunwale455fac52016-07-21 07:24:49 -0700710 "restoreSavedSurfaces: " + this + " allDrawn=" + allDrawn
Chong Zhang92147042016-05-09 12:47:11 -0700711 + " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
Chong Zhangbef461f2015-10-27 11:38:24 -0700712 }
713
714 void destroySavedSurfaces() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700715 for (int i = windows.size() - 1; i >= 0; i--) {
716 WindowState win = windows.get(i);
Robert Carr13f7be9e2015-12-02 18:39:45 -0800717 win.destroySavedSurface();
Chong Zhangbef461f2015-10-27 11:38:24 -0700718 }
Chong Zhang92147042016-05-09 12:47:11 -0700719 }
720
721 void clearAllDrawn() {
722 allDrawn = false;
723 deferClearAllDrawn = false;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700724 allDrawnExcludingSaved = false;
Chong Zhangbef461f2015-10-27 11:38:24 -0700725 }
726
Wale Ogunwale98e70d02014-11-10 12:12:27 -0800727 @Override
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700728 void removeWindow(WindowState win) {
729 super.removeWindow(win);
730
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700731 // TODO: Something smells about the code below...Is there a better way?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700732 if (startingWindow == win) {
733 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700734 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700735 } else if (windows.size() == 0 && startingData != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700736 // If this is the last window and we had requested a starting transition window,
737 // well there is no point now.
738 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
739 startingData = null;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700740 } else if (windows.size() == 1 && startingView != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700741 // If this is the last window except for a starting transition window,
742 // we need to get rid of the starting transition.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700743 mService.scheduleRemoveStartingWindowLocked(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700744 }
745 }
746
Chong Zhang112eb8c2015-11-02 11:17:00 -0800747 void removeAllDeadWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700748 for (int winNdx = windows.size() - 1; winNdx >= 0;
749 // WindowState#removeIfPossible() at bottom of loop may remove multiple entries from
750 // windows if the window to be removed has child windows. It also may
751 // not remove any windows from windows at all if win is exiting and
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700752 // currently animating away. This ensures that winNdx is monotonically decreasing
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700753 // and never beyond windows bounds.
754 winNdx = Math.min(winNdx - 1, windows.size() - 1)) {
755 WindowState win = windows.get(winNdx);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800756 if (win.mAppDied) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700757 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
758 "removeAllDeadWindows: " + win);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800759 // Set mDestroying, we don't want any animation or delayed removal here.
760 win.mDestroying = true;
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700761 win.removeIfPossible();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800762 }
763 }
764 }
765
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700766 boolean hasWindowsAlive() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700767 for (int i = windows.size() - 1; i >= 0; i--) {
768 if (!windows.get(i).mAppDied) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -0700769 return true;
770 }
771 }
772 return false;
773 }
774
Robert Carra1eb4392015-12-10 12:43:51 -0800775 void setReplacingWindows(boolean animate) {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700776 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
777 "Marking app token " + this + " with replacing windows.");
Robert Carra1eb4392015-12-10 12:43:51 -0800778
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700779 for (int i = windows.size() - 1; i >= 0; i--) {
780 final WindowState w = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800781 w.setReplacing(animate);
782 }
783 if (animate) {
784 // Set-up dummy animation so we can start treating windows associated with this
785 // token like they are in transition before the new app window is ready for us to
786 // run the real transition animation.
787 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
788 "setReplacingWindow() Setting dummy animation on: " + this);
789 mAppAnimator.setDummyAnimation();
790 }
791 }
792
Robert Carr23fa16b2016-01-13 13:19:58 -0800793 void setReplacingChildren() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700794 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
Robert Carr23fa16b2016-01-13 13:19:58 -0800795 + " with replacing child windows.");
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700796 for (int i = windows.size() - 1; i >= 0; i--) {
797 final WindowState w = windows.get(i);
Robert Carrd1a010f2016-04-07 22:36:22 -0700798 if (w.shouldBeReplacedWithChildren()) {
Robert Carr23fa16b2016-01-13 13:19:58 -0800799 w.setReplacing(false /* animate */);
800 }
801 }
802 }
803
Chong Zhangf596cd52016-01-05 13:42:44 -0800804 void resetReplacingWindows() {
Wale Ogunwale455fac52016-07-21 07:24:49 -0700805 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
806 "Resetting app token " + this + " of replacing window marks.");
Chong Zhangf596cd52016-01-05 13:42:44 -0800807
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700808 for (int i = windows.size() - 1; i >= 0; i--) {
809 final WindowState w = windows.get(i);
Chong Zhangf596cd52016-01-05 13:42:44 -0800810 w.resetReplacing();
811 }
812 }
813
Chong Zhang4d7369a2016-04-25 16:09:14 -0700814 void requestUpdateWallpaperIfNeeded() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700815 for (int i = windows.size() - 1; i >= 0; i--) {
816 final WindowState w = windows.get(i);
Chong Zhang4d7369a2016-04-25 16:09:14 -0700817 w.requestUpdateWallpaperIfNeeded();
818 }
819 }
820
Chong Zhangd78ddb42016-03-02 17:01:14 -0800821 boolean isRelaunching() {
822 return mPendingRelaunchCount > 0;
823 }
824
825 void startRelaunching() {
826 if (canFreezeBounds()) {
827 freezeBounds();
828 }
829 mPendingRelaunchCount++;
830 }
831
832 void finishRelaunching() {
833 if (canFreezeBounds()) {
834 unfreezeBounds();
835 }
836 if (mPendingRelaunchCount > 0) {
837 mPendingRelaunchCount--;
838 }
839 }
840
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700841 void clearRelaunching() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700842 if (mPendingRelaunchCount == 0) {
843 return;
844 }
Wale Ogunwale8fd75422016-06-24 14:20:37 -0700845 if (canFreezeBounds()) {
846 unfreezeBounds();
847 }
848 mPendingRelaunchCount = 0;
849 }
850
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700851 @Override
Robert Carra1eb4392015-12-10 12:43:51 -0800852 void addWindow(WindowState w) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700853 super.addWindow(w);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700854
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700855 for (int i = windows.size() - 1; i >= 0; i--) {
856 final WindowState candidate = windows.get(i);
857 if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null
858 && candidate.getWindowTag().toString().equals(w.getWindowTag().toString())) {
859
Robert Carra1eb4392015-12-10 12:43:51 -0800860 candidate.mReplacingWindow = w;
Robert Carrb439a632016-04-07 22:52:10 -0700861 w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow;
Chong Zhangf596cd52016-01-05 13:42:44 -0800862 // if we got a replacement window, reset the timeout to give drawing more time
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700863 mService.scheduleReplacingWindowTimeouts(this);
Robert Carra1eb4392015-12-10 12:43:51 -0800864 }
865 }
Robert Carra1eb4392015-12-10 12:43:51 -0800866 }
867
868 boolean waitingForReplacement() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700869 for (int i = windows.size() - 1; i >= 0; i--) {
870 WindowState candidate = windows.get(i);
Robert Carra1eb4392015-12-10 12:43:51 -0800871 if (candidate.mWillReplaceWindow) {
872 return true;
873 }
874 }
875 return false;
876 }
877
Chong Zhangf596cd52016-01-05 13:42:44 -0800878 void clearTimedoutReplacesLocked() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700879 for (int i = windows.size() - 1; i >= 0;
880 // WindowState#remove() at bottom of loop may remove multiple entries from windows if
881 // the window to be removed has child windows. It also may not remove any windows from
882 // windows at all if win is exiting and currently animating away. This ensures that
883 // winNdx is monotonically decreasing and never beyond windows bounds.
884 i = Math.min(i - 1, windows.size() - 1)) {
885 final WindowState candidate = windows.get(i);
886 if (!candidate.mWillReplaceWindow) {
Robert Carra1eb4392015-12-10 12:43:51 -0800887 continue;
888 }
889 candidate.mWillReplaceWindow = false;
Robert Carrb439a632016-04-07 22:52:10 -0700890 if (candidate.mReplacingWindow != null) {
891 candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false;
892 }
Chong Zhangf596cd52016-01-05 13:42:44 -0800893 // Since the window already timed out, remove it immediately now.
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700894 // Use WindowState#remove() instead of WindowState#removeIfPossible(), as the latter
Chong Zhangf596cd52016-01-05 13:42:44 -0800895 // delays removal on certain conditions, which will leave the stale window in the
896 // stack and marked mWillReplaceWindow=false, so the window will never be removed.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700897 candidate.remove();
Robert Carra1eb4392015-12-10 12:43:51 -0800898 }
899 }
900
Chong Zhangd78ddb42016-03-02 17:01:14 -0800901 private boolean canFreezeBounds() {
902 // For freeform windows, we can't freeze the bounds at the moment because this would make
903 // the resizing unresponsive.
904 return mTask != null && !mTask.inFreeformWorkspace();
905 }
906
Jorim Jaggi0429f352015-12-22 16:29:16 +0100907 /**
908 * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
909 * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
910 * if they change in the meantime. If the bounds are already frozen, the bounds will be frozen
911 * with a queue.
912 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800913 private void freezeBounds() {
Jorim Jaggi0429f352015-12-22 16:29:16 +0100914 mFrozenBounds.offer(new Rect(mTask.mPreparedFrozenBounds));
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700915
916 if (mTask.mPreparedFrozenMergedConfig.equals(Configuration.EMPTY)) {
917 // We didn't call prepareFreezingBounds on the task, so use the current value.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700918 final Configuration config = new Configuration(mService.mCurConfiguration);
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700919 config.updateFrom(mTask.mOverrideConfig);
920 mFrozenMergedConfig.offer(config);
921 } else {
922 mFrozenMergedConfig.offer(new Configuration(mTask.mPreparedFrozenMergedConfig));
923 }
924 mTask.mPreparedFrozenMergedConfig.setToDefaults();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100925 }
926
927 /**
928 * Unfreezes the previously frozen bounds. See {@link #freezeBounds}.
929 */
Chong Zhangd78ddb42016-03-02 17:01:14 -0800930 private void unfreezeBounds() {
Wale Ogunwale37dbafc2016-06-27 10:15:20 -0700931 if (!mFrozenBounds.isEmpty()) {
932 mFrozenBounds.remove();
933 }
934 if (!mFrozenMergedConfig.isEmpty()) {
935 mFrozenMergedConfig.remove();
936 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700937 for (int i = windows.size() - 1; i >= 0; i--) {
938 final WindowState win = windows.get(i);
Jorim Jaggi69abc192016-02-04 19:34:00 -0800939 if (!win.mHasSurface) {
940 continue;
941 }
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100942 win.mLayoutNeeded = true;
943 win.setDisplayLayoutNeeded();
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700944 if (!mService.mResizingWindows.contains(win)) {
945 mService.mResizingWindows.add(win);
Jorim Jaggi4846ee32016-01-07 17:39:12 +0100946 }
947 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700948 mService.mWindowPlacerLocked.performSurfacePlacement();
Jorim Jaggi0429f352015-12-22 16:29:16 +0100949 }
950
Robert Carr91b228092016-06-28 17:32:37 -0700951 void addSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
952 mSurfaceViewBackgrounds.add(background);
953 }
954
955 void removeSurfaceViewBackground(WindowSurfaceController.SurfaceControlWithBackground background) {
956 mSurfaceViewBackgrounds.remove(background);
957 updateSurfaceViewBackgroundVisibilities();
958 }
959
960 // We use DimLayers behind SurfaceViews to prevent holes while resizing and creating.
961 // However, we need to ensure one SurfaceView doesn't cover another when they are both placed
962 // below the main app window (as traditionally a SurfaceView which is never drawn
963 // to is totally translucent). So we look at all our SurfaceView backgrounds and only enable
964 // the background for the SurfaceView with lowest Z order
965 void updateSurfaceViewBackgroundVisibilities() {
966 WindowSurfaceController.SurfaceControlWithBackground bottom = null;
967 int bottomLayer = Integer.MAX_VALUE;
968 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
969 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
970 if (sc.mVisible && sc.mLayer < bottomLayer) {
971 bottomLayer = sc.mLayer;
972 bottom = sc;
973 }
974 }
975 for (int i = 0; i < mSurfaceViewBackgrounds.size(); i++) {
976 WindowSurfaceController.SurfaceControlWithBackground sc = mSurfaceViewBackgrounds.get(i);
977 sc.updateBackgroundVisibility(sc != bottom);
978 }
979 }
980
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700981 void resetJustMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700982 for (int i = windows.size() - 1; i >= 0; i--) {
983 windows.get(i).resetJustMovedInStack();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700984 }
985 }
986
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700987 void setWaitingForDrawnIfResizingChanged() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700988 for (int i = windows.size() - 1; i >= 0; --i) {
989 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700990 if (win.isDragResizeChanged()) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700991 mService.mWaitingForDrawn.add(win);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700992 }
993 }
994 }
995
996 void resizeWindows() {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700997 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700998 // Some windows won't go through the resizing process, if they don't have a surface, so
999 // destroy all saved surfaces here.
1000 destroySavedSurfaces();
1001
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001002 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1003 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001004 if (win.mHasSurface && !resizingWindows.contains(win)) {
1005 if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
1006 resizingWindows.add(win);
1007
1008 // If we are not drag resizing, force recreating of a new surface so updating
1009 // the content and positioning that surface will be in sync.
1010 //
1011 // As we use this flag as a hint to freeze surface boundary updates,
1012 // we'd like to only apply this to TYPE_BASE_APPLICATION,
1013 // windows of TYPE_APPLICATION like dialogs, could appear
1014 // to not be drag resizing while they resize, but we'd
1015 // still like to manipulate their frame to update crop, etc...
1016 //
1017 // Anyway we don't need to synchronize position and content updates for these
1018 // windows since they aren't at the base layer and could be moved around anyway.
1019 if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
1020 !mTask.mStack.getBoundsAnimating() && !win.isGoneForLayoutLw() &&
1021 !mTask.inPinnedWorkspace()) {
1022 win.setResizedWhileNotDragResizing(true);
1023 }
1024 }
1025 if (win.isGoneForLayoutLw()) {
1026 win.mResizedWhileGone = true;
1027 }
1028 }
1029 }
1030
1031 void moveWindows() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001032 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1033 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001034 if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
1035 win.mMovedByResize = true;
1036 }
1037 }
1038
1039 void notifyMovedInStack() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001040 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1041 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001042 win.notifyMovedInStack();
1043 }
1044 }
1045
1046 void resetDragResizingChangeReported() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001047 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1048 final WindowState win = windows.get(winNdx);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001049 win.resetDragResizingChangeReported();
1050 }
1051 }
1052
1053 void detachDisplay() {
1054 boolean doAnotherLayoutPass = false;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001055 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001056 // We are in the middle of changing the state of displays/stacks/tasks. We need
1057 // to finish that, before we let layout interfere with it.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001058 windows.get(winNdx).removeIfPossible();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001059 doAnotherLayoutPass = true;
1060 }
1061 if (doAnotherLayoutPass) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001062 mService.mWindowPlacerLocked.requestTraversal();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001063 }
1064 }
1065
1066 void forceWindowsScaleableInTransaction(boolean force) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001067 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1068 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001069 if (winAnimator == null || !winAnimator.hasSurface()) {
1070 continue;
1071 }
1072 winAnimator.mSurfaceController.forceScaleableInTransaction(force);
1073 }
1074 }
1075
1076 boolean isAnimating() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001077 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1078 final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001079 if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
1080 return true;
1081 }
1082 }
1083 return false;
1084 }
1085
1086 void setAppLayoutChanges(int changes, String reason, int displayId) {
1087 final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001088 for (int i = windows.size() - 1; i >= 0; i--) {
1089 if (displayId == windows.get(i).getDisplayId()) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001090 windowAnimator.setPendingLayoutChanges(displayId, changes);
1091 if (DEBUG_LAYOUT_REPEATS) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001092 mService.mWindowPlacerLocked.debugLayoutRepeats(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001093 reason, windowAnimator.getPendingLayoutChanges(displayId));
1094 }
1095 break;
1096 }
1097 }
1098 }
1099
1100 void removeReplacedWindowIfNeeded(WindowState replacement) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001101 for (int i = windows.size() - 1; i >= 0; i--) {
1102 final WindowState win = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001103 if (win.mWillReplaceWindow && win.mReplacingWindow == replacement
1104 && replacement.hasDrawnLw()) {
1105 replacement.mSkipEnterAnimationForSeamlessReplacement = false;
1106 win.removeReplacedWindow();
1107 }
1108 }
1109 }
1110
1111 void startFreezingScreen() {
1112 if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
1113 + hidden + " freezing=" + mAppAnimator.freezingScreen);
1114 if (!hiddenRequested) {
1115 if (!mAppAnimator.freezingScreen) {
1116 mAppAnimator.freezingScreen = true;
1117 mAppAnimator.lastFreezeDuration = 0;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001118 mService.mAppsFreezingScreen++;
1119 if (mService.mAppsFreezingScreen == 1) {
1120 mService.startFreezingDisplayLocked(false, 0, 0);
1121 mService.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
1122 mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001123 }
1124 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001125 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001126 for (int i = 0; i < count; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001127 final WindowState w = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001128 w.mAppFreezing = true;
1129 }
1130 }
1131 }
1132
1133 void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
1134 if (!mAppAnimator.freezingScreen) {
1135 return;
1136 }
1137 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001138 final int count = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001139 boolean unfrozeWindows = false;
1140 for (int i = 0; i < count; i++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001141 final WindowState w = windows.get(i);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001142 if (w.mAppFreezing) {
1143 w.mAppFreezing = false;
1144 if (w.mHasSurface && !w.mOrientationChanging
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001145 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001146 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
1147 w.mOrientationChanging = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001148 mService.mWindowPlacerLocked.mOrientationChangeComplete = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001149 }
1150 w.mLastFreezeDuration = 0;
1151 unfrozeWindows = true;
1152 w.setDisplayLayoutNeeded();
1153 }
1154 }
1155 if (force || unfrozeWindows) {
1156 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
1157 mAppAnimator.freezingScreen = false;
1158 mAppAnimator.lastFreezeDuration =
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001159 (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime);
1160 mService.mAppsFreezingScreen--;
1161 mService.mLastFinishedFreezeSource = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001162 }
1163 if (unfreezeSurfaceNow) {
1164 if (unfrozeWindows) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001165 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001166 }
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001167 mService.stopFreezingDisplayLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001168 }
1169 }
1170
1171 boolean transferStartingWindow(IBinder transferFrom) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001172 final AppWindowToken fromToken = mService.findAppWindowToken(transferFrom);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001173 if (fromToken == null) {
1174 return false;
1175 }
1176
1177 final WindowState tStartingWindow = fromToken.startingWindow;
1178 if (tStartingWindow != null && fromToken.startingView != null) {
1179 // In this case, the starting icon has already been displayed, so start
1180 // letting windows get shown immediately without any more transitions.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001181 mService.mSkipAppTransitionAnimation = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001182
1183 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
1184 + " from " + fromToken + " to " + this);
1185
1186 final long origId = Binder.clearCallingIdentity();
1187
1188 // Transfer the starting window over to the new token.
1189 startingData = fromToken.startingData;
1190 startingView = fromToken.startingView;
1191 startingDisplayed = fromToken.startingDisplayed;
1192 fromToken.startingDisplayed = false;
1193 startingWindow = tStartingWindow;
1194 reportedVisible = fromToken.reportedVisible;
1195 fromToken.startingData = null;
1196 fromToken.startingView = null;
1197 fromToken.startingWindow = null;
1198 fromToken.startingMoved = true;
1199 tStartingWindow.mToken = this;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001200 tStartingWindow.mAppToken = this;
1201
1202 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1203 "Removing starting window: " + tStartingWindow);
1204 tStartingWindow.getWindowList().remove(tStartingWindow);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001205 mService.mWindowsChanged = true;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001206 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1207 "Removing starting " + tStartingWindow + " from " + fromToken);
1208 fromToken.removeWindow(tStartingWindow);
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001209 addWindow(tStartingWindow);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001210
1211 // Propagate other interesting state between the tokens. If the old token is displayed,
1212 // we should immediately force the new one to be displayed. If it is animating, we need
1213 // to move that animation to the new one.
1214 if (fromToken.allDrawn) {
1215 allDrawn = true;
1216 deferClearAllDrawn = fromToken.deferClearAllDrawn;
1217 }
1218 if (fromToken.firstWindowDrawn) {
1219 firstWindowDrawn = true;
1220 }
1221 if (!fromToken.hidden) {
1222 hidden = false;
1223 hiddenRequested = false;
1224 }
1225 if (clientHidden != fromToken.clientHidden) {
1226 clientHidden = fromToken.clientHidden;
1227 sendAppVisibilityToClients();
1228 }
1229 fromToken.mAppAnimator.transferCurrentAnimation(
1230 mAppAnimator, tStartingWindow.mWinAnimator);
1231
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001232 mService.updateFocusedWindowLocked(
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001233 UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001234 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1235 mService.mWindowPlacerLocked.performSurfacePlacement();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001236 Binder.restoreCallingIdentity(origId);
1237 return true;
1238 } else if (fromToken.startingData != null) {
1239 // The previous app was getting ready to show a
1240 // starting window, but hasn't yet done so. Steal it!
1241 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
1242 "Moving pending starting from " + fromToken + " to " + this);
1243 startingData = fromToken.startingData;
1244 fromToken.startingData = null;
1245 fromToken.startingMoved = true;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001246 final Message m = mService.mH.obtainMessage(H.ADD_STARTING, this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001247 // Note: we really want to do sendMessageAtFrontOfQueue() because we want to process the
1248 // message ASAP, before any other queued messages.
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001249 mService.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001250 return true;
1251 }
1252
1253 final AppWindowAnimator tAppAnimator = fromToken.mAppAnimator;
1254 final AppWindowAnimator wAppAnimator = mAppAnimator;
1255 if (tAppAnimator.thumbnail != null) {
1256 // The old token is animating with a thumbnail, transfer that to the new token.
1257 if (wAppAnimator.thumbnail != null) {
1258 wAppAnimator.thumbnail.destroy();
1259 }
1260 wAppAnimator.thumbnail = tAppAnimator.thumbnail;
1261 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
1262 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
1263 tAppAnimator.thumbnail = null;
1264 }
1265 return false;
1266 }
1267
1268 int getWindowsCount() {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001269 return windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001270 }
1271
1272 void setAllAppWinAnimators() {
1273 final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
1274 allAppWinAnimators.clear();
1275
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001276 final int windowsCount = windows.size();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001277 for (int j = 0; j < windowsCount; j++) {
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001278 allAppWinAnimators.add(windows.get(j).mWinAnimator);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001279 }
1280 }
1281
Craig Mautnerdbb79912012-03-01 18:59:14 -08001282 @Override
Wale Ogunwale2049dbf2016-08-02 21:05:23 -07001283 AppWindowToken asAppWindowToken() {
1284 // I am an app window token!
1285 return this;
1286 }
1287
1288 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001289 void dump(PrintWriter pw, String prefix) {
1290 super.dump(pw, prefix);
1291 if (appToken != null) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001292 pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001293 }
Craig Mautner83162a92015-01-26 14:43:30 -08001294 pw.print(prefix); pw.print("task="); pw.println(mTask);
1295 pw.print(prefix); pw.print(" appFullscreen="); pw.print(appFullscreen);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001296 pw.print(" requestedOrientation="); pw.println(requestedOrientation);
1297 pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
1298 pw.print(" clientHidden="); pw.print(clientHidden);
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -07001299 pw.print(" reportedDrawn="); pw.print(reportedDrawn);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001300 pw.print(" reportedVisible="); pw.println(reportedVisible);
Craig Mautner59431632012-04-04 11:56:44 -07001301 if (paused) {
1302 pw.print(prefix); pw.print("paused="); pw.println(paused);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001303 }
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001304 if (mAppStopped) {
1305 pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
1306 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001307 if (numInterestingWindows != 0 || numDrawnWindows != 0
Craig Mautner6fbda632012-07-03 09:26:39 -07001308 || allDrawn || mAppAnimator.allDrawn) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001309 pw.print(prefix); pw.print("numInterestingWindows=");
1310 pw.print(numInterestingWindows);
1311 pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
1312 pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
Craig Mautner6fbda632012-07-03 09:26:39 -07001313 pw.print(" allDrawn="); pw.print(allDrawn);
1314 pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
1315 pw.println(")");
1316 }
1317 if (inPendingTransaction) {
1318 pw.print(prefix); pw.print("inPendingTransaction=");
1319 pw.println(inPendingTransaction);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001320 }
Craig Mautner799bc1d2015-01-14 10:33:48 -08001321 if (startingData != null || removed || firstWindowDrawn || mIsExiting) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001322 pw.print(prefix); pw.print("startingData="); pw.print(startingData);
1323 pw.print(" removed="); pw.print(removed);
Craig Mautner3d7ca312015-01-08 10:56:00 -08001324 pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
Craig Mautner799bc1d2015-01-14 10:33:48 -08001325 pw.print(" mIsExiting="); pw.println(mIsExiting);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001326 }
1327 if (startingWindow != null || startingView != null
1328 || startingDisplayed || startingMoved) {
1329 pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
1330 pw.print(" startingView="); pw.print(startingView);
1331 pw.print(" startingDisplayed="); pw.print(startingDisplayed);
Wale Ogunwale9017ec02016-02-25 08:55:25 -08001332 pw.print(" startingMoved="); pw.println(startingMoved);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001333 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01001334 if (!mFrozenBounds.isEmpty()) {
Chong Zhangd78ddb42016-03-02 17:01:14 -08001335 pw.print(prefix); pw.print("mFrozenBounds="); pw.println(mFrozenBounds);
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001336 pw.print(prefix); pw.print("mFrozenMergedConfig="); pw.println(mFrozenMergedConfig);
Chong Zhangd78ddb42016-03-02 17:01:14 -08001337 }
1338 if (mPendingRelaunchCount != 0) {
1339 pw.print(prefix); pw.print("mPendingRelaunchCount="); pw.println(mPendingRelaunchCount);
Jorim Jaggi0429f352015-12-22 16:29:16 +01001340 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001341 }
1342
1343 @Override
1344 public String toString() {
1345 if (stringName == null) {
1346 StringBuilder sb = new StringBuilder();
1347 sb.append("AppWindowToken{");
1348 sb.append(Integer.toHexString(System.identityHashCode(this)));
1349 sb.append(" token="); sb.append(token); sb.append('}');
1350 stringName = sb.toString();
1351 }
1352 return stringName;
1353 }
Jeff Browne9bdb312012-04-05 15:30:10 -07001354}