blob: 856d30ab7cf137758cd8e207b669ad8729b3d2c3 [file] [log] [blame]
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001package com.android.server.wm;
2
Jorim Jaggi275561a2016-02-23 10:11:02 -05003import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE;
4import static android.app.ActivityManagerInternal.APP_TRANSITION_STARTING_WINDOW;
5import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
6import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07007import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
8import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
9import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
10import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
11import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
12import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
13import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070014import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
15import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
16import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
17import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
18import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
19import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
20import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080021import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
22import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
23import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
27import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
28import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
30import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080033import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070034import static com.android.server.wm.WindowManagerService.H.*;
35import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
36import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080037import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
38import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
39import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070040import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
41import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
42import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
43
44import android.graphics.Bitmap;
45import android.graphics.Canvas;
46import android.graphics.PixelFormat;
47import android.graphics.Rect;
48import android.os.Debug;
Jorim Jaggi275561a2016-02-23 10:11:02 -050049import android.os.Message;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070050import android.os.PowerManager;
51import android.os.RemoteException;
52import android.os.SystemClock;
53import android.os.Trace;
54import android.provider.Settings;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -070055import android.util.ArraySet;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070056import android.util.Slog;
57import android.view.Display;
58import android.view.DisplayInfo;
59import android.view.Surface;
60import android.view.SurfaceControl;
61import android.view.View;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080062import android.view.WindowManager.LayoutParams;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070063import android.view.animation.Animation;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070064
Filip Gruszczynski24966d42015-09-05 15:00:00 -070065import java.io.PrintWriter;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070066import java.util.ArrayList;
67
68/**
69 * Positions windows and their surfaces.
70 *
71 * It sets positions of windows by calculating their frames and then applies this by positioning
72 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
73 */
74class WindowSurfacePlacer {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080075 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070076 private final WindowManagerService mService;
77 private final WallpaperController mWallpaperControllerLocked;
78
79 private boolean mInLayout = false;
80
81 /** Only do a maximum of 6 repeated layouts. After that quit */
82 private int mLayoutRepeatCount;
83
84 static final int SET_UPDATE_ROTATION = 1 << 0;
85 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
86 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
87 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
88 static final int SET_TURN_ON_SCREEN = 1 << 4;
89 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
90
91 boolean mWallpaperMayChange = false;
92 boolean mOrientationChangeComplete = true;
93 boolean mWallpaperActionPending = false;
94
95 private boolean mWallpaperForceHidingChanged = false;
96 private Object mLastWindowFreezeSource = null;
97 private Session mHoldScreen = null;
98 private boolean mObscured = false;
99 private boolean mSyswin = false;
100 private float mScreenBrightness = -1;
101 private float mButtonBrightness = -1;
102 private long mUserActivityTimeout = -1;
103 private boolean mUpdateRotation = false;
104 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800105 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700106
107 // Set to true when the display contains content to show the user.
108 // When false, the display manager may choose to mirror or blank the display.
109 private boolean mDisplayHasContent = false;
110
111 // Only set while traversing the default display based on its content.
112 // Affects the behavior of mirroring on secondary displays.
113 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
114
115 private float mPreferredRefreshRate = 0;
116
117 private int mPreferredModeId = 0;
118
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700119 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +0200120 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700121
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800122 private static final class LayerAndToken {
123 public int layer;
124 public AppWindowToken token;
125 }
126 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
127
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700128 public WindowSurfacePlacer(WindowManagerService service) {
129 mService = service;
130 mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
131 }
132
Jorim Jaggic4025202015-10-22 16:43:34 +0200133 /**
134 * See {@link WindowManagerService#deferSurfaceLayout()}
135 */
136 void deferLayout() {
137 mDeferDepth++;
138 }
139
140 /**
141 * See {@link WindowManagerService#continueSurfaceLayout()}
142 */
143 void continueLayout() {
144 mDeferDepth--;
145 if (mDeferDepth <= 0) {
146 performSurfacePlacement();
147 }
148 }
149
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700150 final void performSurfacePlacement() {
Jorim Jaggic4025202015-10-22 16:43:34 +0200151 if (mDeferDepth > 0) {
152 return;
153 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700154 int loopCount = 6;
155 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700156 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700157 performSurfacePlacementLoop();
158 mService.mH.removeMessages(DO_TRAVERSAL);
159 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700160 } while (mTraversalScheduled && loopCount > 0);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700161 mWallpaperActionPending = false;
162 }
163
164 private void performSurfacePlacementLoop() {
165 if (mInLayout) {
166 if (DEBUG) {
167 throw new RuntimeException("Recursive call!");
168 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800169 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700170 + Debug.getCallers(3));
171 return;
172 }
173
174 if (mService.mWaitingForConfig) {
175 // Our configuration has changed (most likely rotation), but we
176 // don't yet have the complete configuration to report to
177 // applications. Don't do any window layout until we have it.
178 return;
179 }
180
181 if (!mService.mDisplayReady) {
182 // Not yet initialized, nothing to do.
183 return;
184 }
185
186 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
187 mInLayout = true;
188
189 boolean recoveringMemory = false;
190 if (!mService.mForceRemoves.isEmpty()) {
191 recoveringMemory = true;
192 // Wait a little bit for things to settle down, and off we go.
193 while (!mService.mForceRemoves.isEmpty()) {
194 WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800195 Slog.i(TAG, "Force removing: " + ws);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700196 mService.removeWindowInnerLocked(ws);
197 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800198 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700199 Object tmp = new Object();
200 synchronized (tmp) {
201 try {
202 tmp.wait(250);
203 } catch (InterruptedException e) {
204 }
205 }
206 }
207
208 try {
209 performSurfacePlacementInner(recoveringMemory);
210
211 mInLayout = false;
212
213 if (mService.needsLayout()) {
214 if (++mLayoutRepeatCount < 6) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700215 requestTraversal();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700216 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800217 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700218 mLayoutRepeatCount = 0;
219 }
220 } else {
221 mLayoutRepeatCount = 0;
222 }
223
224 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
225 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
226 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
227 }
228 } catch (RuntimeException e) {
229 mInLayout = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800230 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700231 }
232
233 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
234 }
235
236 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
237 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800238 Slog.v(TAG, "Layouts looping: " + msg +
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700239 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
240 }
241 }
242
243 // "Something has changed! Let's make it correct now."
244 private void performSurfacePlacementInner(boolean recoveringMemory) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800245 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
246 + Debug.getCallers(3));
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700247
248 int i;
249 boolean updateInputWindowsNeeded = false;
250
251 if (mService.mFocusMayChange) {
252 mService.mFocusMayChange = false;
253 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
254 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
255 }
256
257 // Initialize state of exiting tokens.
258 final int numDisplays = mService.mDisplayContents.size();
259 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
260 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
261 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
262 displayContent.mExitingTokens.get(i).hasVisible = false;
263 }
264 }
265
266 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
267 // Initialize state of exiting applications.
268 final AppTokenList exitingAppTokens =
269 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
270 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
271 exitingAppTokens.get(tokenNdx).hasVisible = false;
272 }
273 }
274
275 mHoldScreen = null;
276 mScreenBrightness = -1;
277 mButtonBrightness = -1;
278 mUserActivityTimeout = -1;
279 mObscureApplicationContentOnSecondaryDisplays = false;
280
281 mService.mTransactionSequence++;
282
283 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
284 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
285 final int defaultDw = defaultInfo.logicalWidth;
286 final int defaultDh = defaultInfo.logicalHeight;
287
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800288 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700289 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
290 SurfaceControl.openTransaction();
291 try {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700292 applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700293 } catch (RuntimeException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800294 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700295 } finally {
296 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800297 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700298 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
299 }
300
301 final WindowList defaultWindows = defaultDisplay.getWindowList();
302
303 // If we are ready to perform an app transition, check through
304 // all of the app tokens to be shown and see if they are ready
305 // to go.
306 if (mService.mAppTransition.isReady()) {
307 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
308 if (DEBUG_LAYOUT_REPEATS)
309 debugLayoutRepeats("after handleAppTransitionReadyLocked",
310 defaultDisplay.pendingLayoutChanges);
311 }
312
313 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
314 // We have finished the animation of an app transition. To do
315 // this, we have delayed a lot of operations like showing and
316 // hiding apps, moving apps in Z-order, etc. The app token list
317 // reflects the correct Z-order, but the window list may now
318 // be out of sync with it. So here we will just rebuild the
319 // entire app window list. Fun!
320 defaultDisplay.pendingLayoutChanges |=
321 mService.handleAnimatingStoppedAndTransitionLocked();
322 if (DEBUG_LAYOUT_REPEATS)
323 debugLayoutRepeats("after handleAnimStopAndXitionLock",
324 defaultDisplay.pendingLayoutChanges);
325 }
326
327 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
328 && !mService.mAppTransition.isReady()) {
329 // At this point, there was a window with a wallpaper that
330 // was force hiding other windows behind it, but now it
331 // is going away. This may be simple -- just animate
332 // away the wallpaper and its window -- or it may be
333 // hard -- the wallpaper now needs to be shown behind
334 // something that was hidden.
335 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
336 if (DEBUG_LAYOUT_REPEATS)
337 debugLayoutRepeats("after animateAwayWallpaperLocked",
338 defaultDisplay.pendingLayoutChanges);
339 }
340 mWallpaperForceHidingChanged = false;
341
342 if (mWallpaperMayChange) {
343 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800344 Slog.v(TAG, "Wallpaper may change! Adjusting");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700345 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
346 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
347 defaultDisplay.pendingLayoutChanges);
348 }
349
350 if (mService.mFocusMayChange) {
351 mService.mFocusMayChange = false;
352 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
353 false /*updateInputWindows*/)) {
354 updateInputWindowsNeeded = true;
355 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
356 }
357 }
358
359 if (mService.needsLayout()) {
360 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
361 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
362 defaultDisplay.pendingLayoutChanges);
363 }
364
365 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
366 WindowState win = mService.mResizingWindows.get(i);
367 if (win.mAppFreezing) {
368 // Don't remove this window until rotation has completed.
369 continue;
370 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700371 // Discard the saved surface if window size is changed, it can't be reused.
Chong Zhangbef461f2015-10-27 11:38:24 -0700372 if (win.mAppToken != null) {
373 win.mAppToken.destroySavedSurfaces();
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700374 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700375 win.reportResized();
376 mService.mResizingWindows.remove(i);
377 }
378
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800379 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
380 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700381 if (mOrientationChangeComplete) {
382 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
383 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
384 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
385 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
386 }
387 mService.stopFreezingDisplayLocked();
388 }
389
390 // Destroy the surface of any windows that are no longer visible.
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800391 boolean wallpaperDestroyed = false;
392 i = mService.mDestroySurface.size();
393 if (i > 0) {
394 do {
395 i--;
396 WindowState win = mService.mDestroySurface.get(i);
397 win.mDestroying = false;
398 if (mService.mInputMethodWindow == win) {
399 mService.mInputMethodWindow = null;
400 }
401 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
402 wallpaperDestroyed = true;
403 }
Robert Carr13f7be9e2015-12-02 18:39:45 -0800404 win.destroyOrSaveSurface();
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800405 } while (i > 0);
406 mService.mDestroySurface.clear();
407 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700408
409 // Time to remove any exiting tokens?
410 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
411 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
412 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
413 for (i = exitingTokens.size() - 1; i >= 0; i--) {
414 WindowToken token = exitingTokens.get(i);
415 if (!token.hasVisible) {
416 exitingTokens.remove(i);
417 if (token.windowType == TYPE_WALLPAPER) {
418 mWallpaperControllerLocked.removeWallpaperToken(token);
419 }
420 }
421 }
422 }
423
424 // Time to remove any exiting applications?
425 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
426 // Initialize state of exiting applications.
427 final AppTokenList exitingAppTokens =
428 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
429 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
430 AppWindowToken token = exitingAppTokens.get(i);
431 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
432 (!token.mIsExiting || token.allAppWindows.isEmpty())) {
433 // Make sure there is no animation running on this token,
434 // so any windows associated with it will be removed as
435 // soon as their animations are complete
436 token.mAppAnimator.clearAnimation();
437 token.mAppAnimator.animating = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800438 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
439 "performLayout: App token exiting now removed" + token);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700440 token.removeAppFromTaskLocked();
441 }
442 }
443 }
444
445 if (wallpaperDestroyed) {
446 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
447 defaultDisplay.layoutNeeded = true;
448 }
449
450 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
451 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
452 if (displayContent.pendingLayoutChanges != 0) {
453 displayContent.layoutNeeded = true;
454 }
455 }
456
457 // Finally update all input windows now that the window changes have stabilized.
458 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
459
460 mService.setHoldScreenLocked(mHoldScreen);
461 if (!mService.mDisplayFrozen) {
462 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
463 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
464 } else {
465 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
466 toBrightnessOverride(mScreenBrightness));
467 }
468 if (mButtonBrightness < 0
469 || mButtonBrightness > 1.0f) {
470 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
471 } else {
472 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
473 toBrightnessOverride(mButtonBrightness));
474 }
475 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
476 mUserActivityTimeout);
477 }
478
479 if (mService.mTurnOnScreen) {
480 if (mService.mAllowTheaterModeWakeFromLayout
481 || Settings.Global.getInt(mService.mContext.getContentResolver(),
482 Settings.Global.THEATER_MODE_ON, 0) == 0) {
483 if (DEBUG_VISIBILITY || DEBUG_POWER) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800484 Slog.v(TAG, "Turning screen on after layout!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700485 }
486 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
487 "android.server.wm:TURN_ON");
488 }
489 mService.mTurnOnScreen = false;
490 }
491
492 if (mUpdateRotation) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800493 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700494 if (mService.updateRotationUncheckedLocked(false)) {
495 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
496 } else {
497 mUpdateRotation = false;
498 }
499 }
500
501 if (mService.mWaitingForDrawnCallback != null ||
502 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
503 !mUpdateRotation)) {
504 mService.checkDrawnWindowsLocked();
505 }
506
507 final int N = mService.mPendingRemove.size();
508 if (N > 0) {
509 if (mService.mPendingRemoveTmp.length < N) {
510 mService.mPendingRemoveTmp = new WindowState[N+10];
511 }
512 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
513 mService.mPendingRemove.clear();
514 DisplayContentList displayList = new DisplayContentList();
515 for (i = 0; i < N; i++) {
516 WindowState w = mService.mPendingRemoveTmp[i];
517 mService.removeWindowInnerLocked(w);
518 final DisplayContent displayContent = w.getDisplayContent();
519 if (displayContent != null && !displayList.contains(displayContent)) {
520 displayList.add(displayContent);
521 }
522 }
523
524 for (DisplayContent displayContent : displayList) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800525 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700526 displayContent.layoutNeeded = true;
527 }
528 }
529
530 // Remove all deferred displays stacks, tasks, and activities.
531 for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
532 mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
533 }
534
535 if (updateInputWindowsNeeded) {
536 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
537 }
Chong Zhangb15758a2015-11-17 12:12:03 -0800538 mService.setFocusTaskRegionLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700539
540 // Check to see if we are now in a state where the screen should
541 // be enabled, because the window obscured flags have changed.
542 mService.enableScreenIfNeededLocked();
543
544 mService.scheduleAnimationLocked();
545
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800546 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800547 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700548 }
549
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700550 private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
551 int defaultDw, int defaultDh) {
552 if (mService.mWatermark != null) {
553 mService.mWatermark.positionSurface(defaultDw, defaultDh);
554 }
555 if (mService.mStrictModeFlash != null) {
556 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
557 }
558 if (mService.mCircularDisplayMask != null) {
559 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
560 mService.mRotation);
561 }
562 if (mService.mEmulatorDisplayOverlay != null) {
563 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
564 mService.mRotation);
565 }
566
567 boolean focusDisplayed = false;
568
569 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
570 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
571 boolean updateAllDrawn = false;
572 WindowList windows = displayContent.getWindowList();
573 DisplayInfo displayInfo = displayContent.getDisplayInfo();
574 final int displayId = displayContent.getDisplayId();
575 final int dw = displayInfo.logicalWidth;
576 final int dh = displayInfo.logicalHeight;
577 final int innerDw = displayInfo.appWidth;
578 final int innerDh = displayInfo.appHeight;
579 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
580
581 // Reset for each display.
582 mDisplayHasContent = false;
583 mPreferredRefreshRate = 0;
584 mPreferredModeId = 0;
585
586 int repeats = 0;
587 do {
588 repeats++;
589 if (repeats > 6) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800590 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700591 displayContent.layoutNeeded = false;
592 break;
593 }
594
595 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
596 "On entry to LockedInner", displayContent.pendingLayoutChanges);
597
598 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
599 mWallpaperControllerLocked.adjustWallpaperWindows()) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800600 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700601 displayContent.layoutNeeded = true;
602 }
603
604 if (isDefaultDisplay
605 && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800606 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700607 if (mService.updateOrientationFromAppTokensLocked(true)) {
608 displayContent.layoutNeeded = true;
609 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
610 }
611 }
612
613 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
614 displayContent.layoutNeeded = true;
615 }
616
617 // FIRST LOOP: Perform a layout, if needed.
618 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
619 performLayoutLockedInner(displayContent, repeats == 1,
620 false /* updateInputWindows */);
621 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800622 Slog.w(TAG, "Layout repeat skipped after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700623 }
624
625 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
626 // it is animating.
627 displayContent.pendingLayoutChanges = 0;
628
629 if (isDefaultDisplay) {
630 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
631 for (int i = windows.size() - 1; i >= 0; i--) {
632 WindowState w = windows.get(i);
633 if (w.mHasSurface) {
634 mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
635 w.mAttachedWindow);
636 }
637 }
638 displayContent.pendingLayoutChanges |=
639 mService.mPolicy.finishPostLayoutPolicyLw();
640 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
641 displayContent.pendingLayoutChanges);
642 }
643 } while (displayContent.pendingLayoutChanges != 0);
644
645 mObscured = false;
646 mSyswin = false;
647 displayContent.resetDimming();
648
649 // Only used if default window
650 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
651
652 for (int i = windows.size() - 1; i >= 0; i--) {
653 WindowState w = windows.get(i);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700654 final boolean obscuredChanged = w.mObscured != mObscured;
655
656 // Update effect.
657 w.mObscured = mObscured;
658 if (!mObscured) {
Chong Zhang0abb20f2015-11-19 14:17:31 -0800659 handleNotObscuredLocked(w, displayInfo);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700660 }
661
Chong Zhang112eb8c2015-11-02 11:17:00 -0800662 w.applyDimLayerIfNeeded();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700663
664 if (isDefaultDisplay && obscuredChanged
665 && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
666 // This is the wallpaper target and its obscured state
667 // changed... make sure the current wallaper's visibility
668 // has been updated accordingly.
669 mWallpaperControllerLocked.updateWallpaperVisibility();
670 }
671
672 final WindowStateAnimator winAnimator = w.mWinAnimator;
673
674 // If the window has moved due to its containing content frame changing, then
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800675 // notify the listeners and optionally animate it. Simply checking a change of
676 // position is not enough, because being move due to dock divider is not a trigger
677 // for animation.
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700678 if (w.hasMoved()) {
679 // Frame has moved, containing content frame has also moved, and we're not
680 // currently animating... let's do something.
681 final int left = w.mFrame.left;
682 final int top = w.mFrame.top;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800683 final boolean adjustedForMinimizedDockedStack = w.getTask() != null &&
684 w.getTask().mStack.isAdjustedForMinimizedDockedStack();
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800685 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800686 && !w.isDragResizing() && !adjustedForMinimizedDockedStack) {
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800687 winAnimator.setMoveAnimation(left, top);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700688 }
689
690 //TODO (multidisplay): Accessibility supported only for the default display.
691 if (mService.mAccessibilityController != null
692 && displayId == Display.DEFAULT_DISPLAY) {
693 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
694 }
695
696 try {
697 w.mClient.moved(left, top);
698 } catch (RemoteException e) {
699 }
700 }
701
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800702 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700703 w.mContentChanged = false;
Chong Zhangbd0d9372015-12-28 15:18:29 -0800704 w.mMovedByResize = false;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700705
706 // Moved from updateWindowsAndWallpaperLocked().
707 if (w.mHasSurface) {
708 // Take care of the window being ready to display.
709 final boolean committed = winAnimator.commitFinishDrawingLocked();
710 if (isDefaultDisplay && committed) {
711 if (w.mAttrs.type == TYPE_DREAM) {
712 // HACK: When a dream is shown, it may at that
713 // point hide the lock screen. So we need to
714 // redo the layout to let the phone window manager
715 // make this happen.
716 displayContent.pendingLayoutChanges |=
717 FINISH_LAYOUT_REDO_LAYOUT;
718 if (DEBUG_LAYOUT_REPEATS) {
719 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
720 displayContent.pendingLayoutChanges);
721 }
722 }
723 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
724 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800725 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700726 mWallpaperMayChange = true;
727 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
728 if (DEBUG_LAYOUT_REPEATS) {
729 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
730 displayContent.pendingLayoutChanges);
731 }
732 }
733 }
Filip Gruszczynskic46f41c2016-01-05 11:29:21 -0800734 if (!winAnimator.isAnimating()) {
735 // Updates the shown frame before we set up the surface. This is needed
736 // because the resizing could change the top-left position (in addition to
737 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
738 // position the surface. We only apply it to windows that aren't animating,
739 // because we depend on the animation to calculate the correct shown frame
740 // on the next animation step.
741 winAnimator.computeShownFrameLocked();
742 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700743 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
744 }
745
746 final AppWindowToken atoken = w.mAppToken;
747 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800748 Slog.d(TAG, "updateWindows: starting " + w
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700749 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
750 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
751 }
752 if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
753 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
754 atoken.lastTransactionSequence = mService.mTransactionSequence;
755 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
756 atoken.startingDisplayed = false;
757 }
758 if ((w.isOnScreenIgnoringKeyguard()
759 || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800760 && !w.mAnimatingExit && !w.mDestroying) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700761 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800762 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700763 + w.isDrawnLw()
764 + ", isAnimating=" + winAnimator.isAnimating());
765 if (!w.isDrawnLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800766 Slog.v(TAG, "Not displayed: s="
Robert Carre6a83512015-11-03 16:09:21 -0800767 + winAnimator.mSurfaceController
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700768 + " pv=" + w.mPolicyVisibility
769 + " mDrawState=" + winAnimator.drawStateToString()
770 + " ah=" + w.mAttachedHidden
771 + " th=" + atoken.hiddenRequested
772 + " a=" + winAnimator.mAnimating);
773 }
774 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800775 if (w != atoken.startingWindow) {
776 if (!w.mAppDied &&
777 (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing)) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700778 atoken.numInterestingWindows++;
779 if (w.isDrawnLw()) {
780 atoken.numDrawnWindows++;
781 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800782 Slog.v(TAG, "tokenMayBeDrawn: " + atoken
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700783 + " freezingScreen="
784 + atoken.mAppAnimator.freezingScreen
785 + " mAppFreezing=" + w.mAppFreezing);
786 updateAllDrawn = true;
787 }
788 }
789 } else if (w.isDrawnLw()) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500790 mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700791 atoken.startingDisplayed = true;
792 }
793 }
794 }
795
796 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
797 && w.isDisplayedLw()) {
798 focusDisplayed = true;
799 }
800
801 mService.updateResizingWindows(w);
802 }
803
804 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
805 mDisplayHasContent,
806 mPreferredRefreshRate,
807 mPreferredModeId,
808 true /* inTraversal, must call performTraversalInTrans... below */);
809
810 mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
811
812 if (updateAllDrawn) {
813 updateAllDrawnLocked(displayContent);
814 }
815 }
816
817 if (focusDisplayed) {
818 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
819 }
820
821 // Give the display manager a chance to adjust properties
822 // like display rotation if it needs to.
823 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
824 }
825
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700826 boolean isInLayout() {
827 return mInLayout;
828 }
829
830 final void performLayoutLockedInner(final DisplayContent displayContent,
831 boolean initial, boolean updateInputWindows) {
832 if (!displayContent.layoutNeeded) {
833 return;
834 }
835 displayContent.layoutNeeded = false;
836 WindowList windows = displayContent.getWindowList();
837 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
838
839 DisplayInfo displayInfo = displayContent.getDisplayInfo();
840 final int dw = displayInfo.logicalWidth;
841 final int dh = displayInfo.logicalHeight;
842
843 if (mService.mInputConsumer != null) {
844 mService.mInputConsumer.layout(dw, dh);
845 }
846
847 final int N = windows.size();
848 int i;
849
850 if (DEBUG_LAYOUT) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800851 Slog.v(TAG, "-------------------------------------");
852 Slog.v(TAG, "performLayout: needed="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700853 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
854 }
855
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800856 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
857 mService.mCurConfiguration.uiMode);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700858 if (isDefaultDisplay) {
859 // Not needed on non-default displays.
860 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
861 mService.mScreenRect.set(0, 0, dw, dh);
862 }
863
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800864 mService.mPolicy.getContentRectLw(mTmpContentRect);
865 displayContent.resize(mTmpContentRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700866
867 int seq = mService.mLayoutSeq+1;
868 if (seq < 0) seq = 0;
869 mService.mLayoutSeq = seq;
870
871 boolean behindDream = false;
872
873 // First perform layout of any root windows (not attached
874 // to another window).
875 int topAttached = -1;
876 for (i = N-1; i >= 0; i--) {
877 final WindowState win = windows.get(i);
878
879 // Don't do layout of a window if it is not visible, or
880 // soon won't be visible, to avoid wasting time and funky
881 // changes while a window is animating away.
882 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
883 || win.isGoneForLayoutLw();
884
885 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800886 Slog.v(TAG, "1ST PASS " + win
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700887 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
888 + " mLayoutAttached=" + win.mLayoutAttached
889 + " screen changed=" + win.isConfigChanged());
890 final AppWindowToken atoken = win.mAppToken;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800891 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700892 + win.mViewVisibility + " mRelayoutCalled="
893 + win.mRelayoutCalled + " hidden="
894 + win.mRootToken.hidden + " hiddenRequested="
895 + (atoken != null && atoken.hiddenRequested)
896 + " mAttachedHidden=" + win.mAttachedHidden);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800897 else Slog.v(TAG, " VIS: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700898 + win.mViewVisibility + " mRelayoutCalled="
899 + win.mRelayoutCalled + " hidden="
900 + win.mRootToken.hidden + " hiddenRequested="
901 + (atoken != null && atoken.hiddenRequested)
902 + " mAttachedHidden=" + win.mAttachedHidden);
903 }
904
905 // If this view is GONE, then skip it -- keep the current
906 // frame, and let the caller know so they can ignore it
907 // if they want. (We do the normal layout for INVISIBLE
908 // windows, since that means "perform layout as normal,
909 // just don't display").
910 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
911 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
912 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
913 (win.mHasSurface && win.mAppToken != null &&
914 win.mAppToken.layoutConfigChanges)))) {
915 if (!win.mLayoutAttached) {
916 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800917 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700918 win.mContentChanged = false;
919 }
920 if (win.mAttrs.type == TYPE_DREAM) {
921 // Don't layout windows behind a dream, so that if it
922 // does stuff like hide the status bar we won't get a
923 // bad transition when it goes away.
924 behindDream = true;
925 }
926 win.mLayoutNeeded = false;
927 win.prelayout();
928 mService.mPolicy.layoutWindowLw(win, null);
929 win.mLayoutSeq = seq;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800930
931 // Window frames may have changed. Update dim layer with the new bounds.
932 final Task task = win.getTask();
933 if (task != null) {
934 displayContent.mDimLayerController.updateDimLayer(task);
935 }
936
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800937 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700938 " LAYOUT: mFrame="
939 + win.mFrame + " mContainingFrame="
940 + win.mContainingFrame + " mDisplayFrame="
941 + win.mDisplayFrame);
942 } else {
943 if (topAttached < 0) topAttached = i;
944 }
945 }
946 }
947
948 boolean attachedBehindDream = false;
949
950 // Now perform layout of attached windows, which usually
951 // depend on the position of the window they are attached to.
952 // XXX does not deal with windows that are attached to windows
953 // that are themselves attached.
954 for (i = topAttached; i >= 0; i--) {
955 final WindowState win = windows.get(i);
956
957 if (win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800958 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700959 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
960 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
961 // If this view is GONE, then skip it -- keep the current
962 // frame, and let the caller know so they can ignore it
963 // if they want. (We do the normal layout for INVISIBLE
964 // windows, since that means "perform layout as normal,
965 // just don't display").
966 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
967 continue;
968 }
969 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
970 || !win.mHaveFrame || win.mLayoutNeeded) {
971 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800972 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700973 win.mContentChanged = false;
974 }
975 win.mLayoutNeeded = false;
976 win.prelayout();
977 mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
978 win.mLayoutSeq = seq;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800979 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700980 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
981 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
982 }
983 } else if (win.mAttrs.type == TYPE_DREAM) {
984 // Don't layout windows behind a dream, so that if it
985 // does stuff like hide the status bar we won't get a
986 // bad transition when it goes away.
987 attachedBehindDream = behindDream;
988 }
989 }
990
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800991 // Window frames may have changed. Tell the input dispatcher about it.
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700992 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
993 if (updateInputWindows) {
994 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
995 }
996
997 mService.mPolicy.finishLayoutLw();
Jorim Jaggi61f39a72015-10-29 16:54:18 +0100998 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700999 }
1000
1001 /**
1002 * @param windows List of windows on default display.
1003 * @return bitmap indicating if another pass through layout must be made.
1004 */
1005 private int handleAppTransitionReadyLocked(WindowList windows) {
1006 int appsCount = mService.mOpeningApps.size();
1007 if (!transitionGoodToGo(appsCount)) {
1008 return 0;
1009 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001010 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001011 int transit = mService.mAppTransition.getAppTransition();
1012 if (mService.mSkipAppTransitionAnimation) {
1013 transit = AppTransition.TRANSIT_UNSET;
1014 }
1015 mService.mSkipAppTransitionAnimation = false;
1016 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1017
1018 mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
1019
1020 mService.rebuildAppWindowListLocked();
1021
1022 mWallpaperMayChange = false;
1023
1024 // The top-most window will supply the layout params,
1025 // and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001026 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001027 int bestAnimLayer = -1;
1028 boolean fullscreenAnim = false;
1029 boolean voiceInteraction = false;
1030
1031 final WindowState lowerWallpaperTarget =
1032 mWallpaperControllerLocked.getLowerWallpaperTarget();
1033 final WindowState upperWallpaperTarget =
1034 mWallpaperControllerLocked.getUpperWallpaperTarget();
1035
1036 boolean openingAppHasWallpaper = false;
1037 boolean closingAppHasWallpaper = false;
1038 final AppWindowToken lowerWallpaperAppToken;
1039 final AppWindowToken upperWallpaperAppToken;
1040 if (lowerWallpaperTarget == null) {
1041 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1042 } else {
1043 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1044 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1045 }
1046
1047 int i;
1048 // Do a first pass through the tokens for two
1049 // things:
1050 // (1) Determine if both the closing and opening
1051 // app token sets are wallpaper targets, in which
1052 // case special animations are needed
1053 // (since the wallpaper needs to stay static
1054 // behind them).
1055 // (2) Find the layout params of the top-most
1056 // application window in the tokens, which is
1057 // what will control the animation theme.
1058 final int closingAppsCount = mService.mClosingApps.size();
1059 appsCount = closingAppsCount + mService.mOpeningApps.size();
1060 for (i = 0; i < appsCount; i++) {
1061 final AppWindowToken wtoken;
1062 if (i < closingAppsCount) {
1063 wtoken = mService.mClosingApps.valueAt(i);
1064 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1065 closingAppHasWallpaper = true;
1066 }
1067 } else {
1068 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1069 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1070 openingAppHasWallpaper = true;
1071 }
1072 }
1073
1074 voiceInteraction |= wtoken.voiceInteraction;
1075
1076 if (wtoken.appFullscreen) {
1077 WindowState ws = wtoken.findMainWindow();
1078 if (ws != null) {
1079 animLp = ws.mAttrs;
1080 bestAnimLayer = ws.mLayer;
1081 fullscreenAnim = true;
1082 }
1083 } else if (!fullscreenAnim) {
1084 WindowState ws = wtoken.findMainWindow();
1085 if (ws != null) {
1086 if (ws.mLayer > bestAnimLayer) {
1087 animLp = ws.mAttrs;
1088 bestAnimLayer = ws.mLayer;
1089 }
1090 }
1091 }
1092 }
1093
1094 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1095 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1096
1097 // If all closing windows are obscured, then there is
1098 // no need to do an animation. This is the case, for
1099 // example, when this transition is being done behind
1100 // the lock screen.
1101 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001102 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001103 "Animations disallowed by keyguard or dream.");
1104 animLp = null;
1105 }
1106
1107 processApplicationsAnimatingInPlace(transit);
1108
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001109 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001110 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1111 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1112 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001113
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001114 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1115 animLp, voiceInteraction, topClosingLayer);
1116
1117 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1118 topOpeningApp.mAppAnimator;
1119 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1120 topClosingApp.mAppAnimator;
1121
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001122 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1123 mService.mOpeningApps, mService.mClosingApps);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001124 mService.mAppTransition.postAnimationCallback();
1125 mService.mAppTransition.clear();
1126
1127 mService.mOpeningApps.clear();
1128 mService.mClosingApps.clear();
1129
1130 // This has changed the visibility of windows, so perform
1131 // a new layout to get them all up-to-date.
1132 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1133
1134 // TODO(multidisplay): IMEs are only supported on the default display.
1135 if (windows == mService.getDefaultWindowListLocked()
1136 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001137 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001138 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001139 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1140 true /*updateInputWindows*/);
1141 mService.mFocusMayChange = false;
1142 mService.notifyActivityDrawnForKeyguard();
1143 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1144 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001145
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001146 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1147 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001148 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001149 final int appsCount = mService.mOpeningApps.size();
1150 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001151 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1152 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001153 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001154
1155 if (!appAnimator.usingTransferredAnimation) {
1156 appAnimator.clearThumbnail();
1157 appAnimator.animation = null;
1158 }
1159 wtoken.inPendingTransaction = false;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001160
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001161 if (!mService.setTokenVisibilityLocked(
1162 wtoken, animLp, true, transit, false, voiceInteraction)){
1163 // This token isn't going to be animating. Add it to the list of tokens to
1164 // be notified of app transition complete since the notification will not be
1165 // sent be the app window animator.
1166 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1167 }
1168 wtoken.updateReportedVisibilityLocked();
1169 wtoken.waitingToShow = false;
1170
1171 appAnimator.mAllAppWinAnimators.clear();
1172 final int windowsCount = wtoken.allAppWindows.size();
1173 for (int j = 0; j < windowsCount; j++) {
1174 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1175 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001176 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001177 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1178 SurfaceControl.openTransaction();
1179 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001180 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001181 } finally {
1182 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001183 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001184 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1185 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001186 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1187
1188 int topOpeningLayer = 0;
1189 if (animLp != null) {
1190 int layer = -1;
1191 for (int j = 0; j < wtoken.windows.size(); j++) {
Chong Zhangbef461f2015-10-27 11:38:24 -07001192 final WindowState win = wtoken.windows.get(j);
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001193 // Clearing the mAnimatingExit flag before entering animation. It will be set to true
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001194 // if app window is removed, or window relayout to invisible. We don't want to
1195 // clear it out for windows that get replaced, because the animation depends on
1196 // the flag to remove the replaced window.
Robert Carr7fed68d2016-01-19 21:24:57 -08001197 //
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001198 // We also don't clear the mAnimatingExit flag for windows which have the
Robert Carr7fed68d2016-01-19 21:24:57 -08001199 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
1200 // by the client. We should let animation proceed and not clear this flag or
1201 // they won't eventually be removed by WindowStateAnimator#finishExit.
1202 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001203 win.mAnimatingExit = false;
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001204 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001205 if (win.mWinAnimator.mAnimLayer > layer) {
1206 layer = win.mWinAnimator.mAnimLayer;
1207 }
1208 }
1209 if (topOpeningApp == null || layer > topOpeningLayer) {
1210 topOpeningApp = wtoken;
1211 topOpeningLayer = layer;
1212 }
1213 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001214 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1215 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1216 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001217 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001218 return topOpeningApp;
1219 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001220
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001221 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1222 LayerAndToken layerAndToken) {
1223 final int appsCount;
1224 appsCount = mService.mClosingApps.size();
1225 for (int i = 0; i < appsCount; i++) {
1226 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1227 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001228 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001229 appAnimator.clearThumbnail();
1230 appAnimator.animation = null;
1231 wtoken.inPendingTransaction = false;
1232 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1233 voiceInteraction);
1234 wtoken.updateReportedVisibilityLocked();
1235 // Force the allDrawn flag, because we want to start
1236 // this guy's animations regardless of whether it's
1237 // gotten drawn.
1238 wtoken.allDrawn = true;
1239 wtoken.deferClearAllDrawn = false;
1240 // Ensure that apps that are mid-starting are also scheduled to have their
1241 // starting windows removed after the animation is complete
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001242 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001243 mService.scheduleRemoveStartingWindowLocked(wtoken);
1244 }
1245 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001246
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001247 if (animLp != null) {
1248 int layer = -1;
1249 for (int j = 0; j < wtoken.windows.size(); j++) {
1250 WindowState win = wtoken.windows.get(j);
1251 if (win.mWinAnimator.mAnimLayer > layer) {
1252 layer = win.mWinAnimator.mAnimLayer;
1253 }
1254 }
1255 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1256 layerAndToken.token = wtoken;
1257 layerAndToken.layer = layer;
1258 }
1259 }
1260 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1261 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1262 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001263 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001264 }
1265
1266 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001267 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001268 "Checking " + appsCount + " opening apps (frozen="
1269 + mService.mDisplayFrozen + " timeout="
1270 + mService.mAppTransition.isTimeout() + ")...");
Jorim Jaggi275561a2016-02-23 10:11:02 -05001271 int reason = APP_TRANSITION_TIMEOUT;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001272 if (!mService.mAppTransition.isTimeout()) {
1273 for (int i = 0; i < appsCount; i++) {
1274 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001275 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001276 "Check opening app=" + wtoken + ": allDrawn="
1277 + wtoken.allDrawn + " startingDisplayed="
1278 + wtoken.startingDisplayed + " startingMoved="
1279 + wtoken.startingMoved);
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001280
Jorim Jaggi275561a2016-02-23 10:11:02 -05001281 final boolean drawnBeforeRestoring = wtoken.allDrawn;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -08001282 wtoken.restoreSavedSurfaces();
1283
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001284 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1285 return false;
1286 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001287 if (wtoken.allDrawn) {
1288 reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1289 : APP_TRANSITION_SAVED_SURFACE;
1290 } else {
1291 reason = APP_TRANSITION_STARTING_WINDOW;
1292 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001293 }
1294
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001295 // We also need to wait for the specs to be fetched, if needed.
1296 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001297 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001298 return false;
1299 }
1300
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001301 // If the wallpaper is visible, we need to check it's ready too.
Jorim Jaggi275561a2016-02-23 10:11:02 -05001302 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001303 mWallpaperControllerLocked.wallpaperTransitionReady();
Jorim Jaggi275561a2016-02-23 10:11:02 -05001304 if (wallpaperReady) {
1305 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1306 return true;
1307 }
1308 return false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001309 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001310 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001311 return true;
1312 }
1313
1314 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1315 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1316 WindowState upperWallpaperTarget) {
1317 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1318 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1319 final WindowState oldWallpaper =
1320 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1321 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001322 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1323 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001324 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001325 "New wallpaper target=" + wallpaperTarget
1326 + ", oldWallpaper=" + oldWallpaper
1327 + ", lower target=" + lowerWallpaperTarget
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001328 + ", upper target=" + upperWallpaperTarget
1329 + ", openingApps=" + openingApps
1330 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001331 mService.mAnimateWallpaperWithTarget = false;
1332 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1333 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001334 Slog.v(TAG, "Wallpaper animation!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001335 switch (transit) {
1336 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1337 case AppTransition.TRANSIT_TASK_OPEN:
1338 case AppTransition.TRANSIT_TASK_TO_FRONT:
1339 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1340 break;
1341 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1342 case AppTransition.TRANSIT_TASK_CLOSE:
1343 case AppTransition.TRANSIT_TASK_TO_BACK:
1344 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1345 break;
1346 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001347 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001348 "New transit: " + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001349 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1350 && !openingApps.contains(oldWallpaper.mAppToken)
1351 && closingApps.contains(oldWallpaper.mAppToken)) {
1352 // We are transitioning from an activity with a wallpaper to one without.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001353 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001354 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001355 "New transit away from wallpaper: "
1356 + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001357 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1358 openingApps.contains(wallpaperTarget.mAppToken)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001359 // We are transitioning from an activity without
1360 // a wallpaper to now showing the wallpaper
1361 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001362 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001363 "New transit into wallpaper: "
1364 + AppTransition.appTransitionToString(transit));
1365 } else {
1366 mService.mAnimateWallpaperWithTarget = true;
1367 }
1368 return transit;
1369 }
1370
1371 /**
1372 * @param w WindowState this method is applied to.
Chong Zhang0abb20f2015-11-19 14:17:31 -08001373 * @param dispInfo info of the display that the window's obscuring state is checked against.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001374 */
Chong Zhang0abb20f2015-11-19 14:17:31 -08001375 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001376 final LayoutParams attrs = w.mAttrs;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001377 final int attrFlags = attrs.flags;
1378 final boolean canBeSeen = w.isDisplayedLw();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001379
Chong Zhang0abb20f2015-11-19 14:17:31 -08001380 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001381 // This window completely covers everything behind it,
1382 // so we want to leave all of them as undimmed (for
1383 // performance reasons).
1384 mObscured = true;
1385 }
1386
1387 if (w.mHasSurface) {
1388 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1389 mHoldScreen = w.mSession;
1390 }
1391 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1392 && mScreenBrightness < 0) {
1393 mScreenBrightness = w.mAttrs.screenBrightness;
1394 }
1395 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1396 && mButtonBrightness < 0) {
1397 mButtonBrightness = w.mAttrs.buttonBrightness;
1398 }
1399 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1400 && mUserActivityTimeout < 0) {
1401 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1402 }
1403
1404 final int type = attrs.type;
1405 if (canBeSeen
1406 && (type == TYPE_SYSTEM_DIALOG
1407 || type == TYPE_SYSTEM_ERROR
1408 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1409 mSyswin = true;
1410 }
1411
1412 if (canBeSeen) {
1413 // This function assumes that the contents of the default display are
1414 // processed first before secondary displays.
1415 final DisplayContent displayContent = w.getDisplayContent();
1416 if (displayContent != null && displayContent.isDefaultDisplay) {
1417 // While a dream or keyguard is showing, obscure ordinary application
1418 // content on secondary displays (by forcibly enabling mirroring unless
1419 // there is other content we want to show) but still allow opaque
1420 // keyguard dialogs to be shown.
1421 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1422 mObscureApplicationContentOnSecondaryDisplays = true;
1423 }
1424 mDisplayHasContent = true;
1425 } else if (displayContent != null &&
1426 (!mObscureApplicationContentOnSecondaryDisplays
1427 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1428 // Allow full screen keyguard presentation dialogs to be seen.
1429 mDisplayHasContent = true;
1430 }
1431 if (mPreferredRefreshRate == 0
1432 && w.mAttrs.preferredRefreshRate != 0) {
1433 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1434 }
1435 if (mPreferredModeId == 0
1436 && w.mAttrs.preferredDisplayModeId != 0) {
1437 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1438 }
1439 }
1440 }
1441 }
1442
1443 private void updateAllDrawnLocked(DisplayContent displayContent) {
1444 // See if any windows have been drawn, so they (and others
1445 // associated with them) can now be shown.
1446 ArrayList<TaskStack> stacks = displayContent.getStacks();
1447 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1448 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1449 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1450 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1451 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1452 final AppWindowToken wtoken = tokens.get(tokenNdx);
1453 if (!wtoken.allDrawn) {
1454 int numInteresting = wtoken.numInterestingWindows;
1455 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1456 if (DEBUG_VISIBILITY)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001457 Slog.v(TAG, "allDrawn: " + wtoken
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001458 + " interesting=" + numInteresting
1459 + " drawn=" + wtoken.numDrawnWindows);
1460 wtoken.allDrawn = true;
1461 // Force an additional layout pass where WindowStateAnimator#
1462 // commitFinishDrawingLocked() will call performShowLocked().
1463 displayContent.layoutNeeded = true;
1464 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1465 wtoken.token).sendToTarget();
1466 }
1467 }
1468 }
1469 }
1470 }
1471 }
1472
1473 private static int toBrightnessOverride(float value) {
1474 return (int)(value * PowerManager.BRIGHTNESS_ON);
1475 }
1476
1477 private void processApplicationsAnimatingInPlace(int transit) {
1478 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1479 // Find the focused window
1480 final WindowState win = mService.findFocusedWindowLocked(
1481 mService.getDefaultDisplayContentLocked());
1482 if (win != null) {
1483 final AppWindowToken wtoken = win.mAppToken;
1484 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1485 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001486 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001487 appAnimator.clearThumbnail();
1488 appAnimator.animation = null;
1489 mService.updateTokenInPlaceLocked(wtoken, transit);
1490 wtoken.updateReportedVisibilityLocked();
1491
1492 appAnimator.mAllAppWinAnimators.clear();
1493 final int N = wtoken.allAppWindows.size();
1494 for (int j = 0; j < N; j++) {
1495 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1496 }
1497 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001498 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001499 }
1500 }
1501 }
1502
1503 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1504 int openingLayer, int closingLayer) {
1505 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1506 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1507 return;
1508 }
1509 final int taskId = appToken.mTask.mTaskId;
1510 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1511 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001512 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001513 return;
1514 }
1515 // This thumbnail animation is very special, we need to have
1516 // an extra surface with the thumbnail included with the animation.
1517 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1518 try {
1519 // TODO(multi-display): support other displays
1520 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1521 final Display display = displayContent.getDisplay();
1522 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1523
1524 // Create a new surface for the thumbnail
1525 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1526 "thumbnail anim", dirty.width(), dirty.height(),
1527 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1528 surfaceControl.setLayerStack(display.getLayerStack());
1529 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001530 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001531 }
1532
1533 // Draw the thumbnail onto the surface
1534 Surface drawSurface = new Surface();
1535 drawSurface.copyFrom(surfaceControl);
1536 Canvas c = drawSurface.lockCanvas(dirty);
1537 c.drawBitmap(thumbnailHeader, 0, 0, null);
1538 drawSurface.unlockCanvasAndPost(c);
1539 drawSurface.release();
1540
1541 // Get the thumbnail animation
1542 Animation anim;
1543 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1544 // If this is a multi-window scenario, we use the windows frame as
1545 // destination of the thumbnail header animation. If this is a full screen
1546 // window scenario, we use the whole display as the target.
1547 WindowState win = appToken.findMainWindow();
1548 Rect appRect = win != null ? win.getContentFrameLw() :
1549 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1550 // For the new aspect-scaled transition, we want it to always show
1551 // above the animating opening/closing window, and we want to
1552 // synchronize its thumbnail surface with the surface for the
1553 // open/close animation (only on the way down)
1554 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
1555 thumbnailHeader, taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001556 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1557 openingAppAnimator.deferThumbnailDestruction =
1558 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1559 } else {
1560 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1561 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1562 }
1563 anim.restrictDuration(MAX_ANIMATION_DURATION);
1564 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1565
1566 openingAppAnimator.thumbnail = surfaceControl;
1567 openingAppAnimator.thumbnailLayer = openingLayer;
1568 openingAppAnimator.thumbnailAnimation = anim;
1569 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
1570 openingAppAnimator.thumbnailX = mTmpStartRect.left;
1571 openingAppAnimator.thumbnailY = mTmpStartRect.top;
1572 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001573 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001574 + dirty.width() + " h=" + dirty.height(), e);
1575 openingAppAnimator.clearThumbnail();
1576 }
1577 }
1578
1579 boolean copyAnimToLayoutParamsLocked() {
1580 boolean doRequest = false;
1581
1582 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1583 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1584 mUpdateRotation = true;
1585 doRequest = true;
1586 }
1587 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1588 mWallpaperMayChange = true;
1589 doRequest = true;
1590 }
1591 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1592 mWallpaperForceHidingChanged = true;
1593 doRequest = true;
1594 }
1595 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1596 mOrientationChangeComplete = false;
1597 } else {
1598 mOrientationChangeComplete = true;
1599 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1600 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1601 doRequest = true;
1602 }
1603 }
1604 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1605 mService.mTurnOnScreen = true;
1606 }
1607 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1608 mWallpaperActionPending = true;
1609 }
1610
1611 return doRequest;
1612 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001613
1614 void requestTraversal() {
1615 if (!mTraversalScheduled) {
1616 mTraversalScheduled = true;
1617 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1618 }
1619 }
1620
1621 public void dump(PrintWriter pw, String prefix) {
1622 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1623 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001624}