blob: 8ada2f1a1646b9a6d10f46f2d5175ddc55dcb5a2 [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;
49import android.os.PowerManager;
50import android.os.RemoteException;
51import android.os.SystemClock;
52import android.os.Trace;
53import android.provider.Settings;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -070054import android.util.ArraySet;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070055import android.util.Slog;
56import android.view.Display;
57import android.view.DisplayInfo;
58import android.view.Surface;
59import android.view.SurfaceControl;
60import android.view.View;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080061import android.view.WindowManager.LayoutParams;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070062import android.view.animation.Animation;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070063
Filip Gruszczynski24966d42015-09-05 15:00:00 -070064import java.io.PrintWriter;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070065import java.util.ArrayList;
66
67/**
68 * Positions windows and their surfaces.
69 *
70 * It sets positions of windows by calculating their frames and then applies this by positioning
71 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
72 */
73class WindowSurfacePlacer {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080074 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070075 private final WindowManagerService mService;
76 private final WallpaperController mWallpaperControllerLocked;
77
78 private boolean mInLayout = false;
79
80 /** Only do a maximum of 6 repeated layouts. After that quit */
81 private int mLayoutRepeatCount;
82
83 static final int SET_UPDATE_ROTATION = 1 << 0;
84 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
85 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
86 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
87 static final int SET_TURN_ON_SCREEN = 1 << 4;
88 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
89
90 boolean mWallpaperMayChange = false;
91 boolean mOrientationChangeComplete = true;
92 boolean mWallpaperActionPending = false;
93
94 private boolean mWallpaperForceHidingChanged = false;
95 private Object mLastWindowFreezeSource = null;
96 private Session mHoldScreen = null;
97 private boolean mObscured = false;
98 private boolean mSyswin = false;
99 private float mScreenBrightness = -1;
100 private float mButtonBrightness = -1;
101 private long mUserActivityTimeout = -1;
102 private boolean mUpdateRotation = false;
103 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800104 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700105
106 // Set to true when the display contains content to show the user.
107 // When false, the display manager may choose to mirror or blank the display.
108 private boolean mDisplayHasContent = false;
109
110 // Only set while traversing the default display based on its content.
111 // Affects the behavior of mirroring on secondary displays.
112 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
113
114 private float mPreferredRefreshRate = 0;
115
116 private int mPreferredModeId = 0;
117
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700118 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +0200119 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700120
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800121 private static final class LayerAndToken {
122 public int layer;
123 public AppWindowToken token;
124 }
125 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
126
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100127 private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
128
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700129 public WindowSurfacePlacer(WindowManagerService service) {
130 mService = service;
131 mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
132 }
133
Jorim Jaggic4025202015-10-22 16:43:34 +0200134 /**
135 * See {@link WindowManagerService#deferSurfaceLayout()}
136 */
137 void deferLayout() {
138 mDeferDepth++;
139 }
140
141 /**
142 * See {@link WindowManagerService#continueSurfaceLayout()}
143 */
144 void continueLayout() {
145 mDeferDepth--;
146 if (mDeferDepth <= 0) {
147 performSurfacePlacement();
148 }
149 }
150
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700151 final void performSurfacePlacement() {
Jorim Jaggic4025202015-10-22 16:43:34 +0200152 if (mDeferDepth > 0) {
153 return;
154 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700155 int loopCount = 6;
156 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700157 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700158 performSurfacePlacementLoop();
159 mService.mH.removeMessages(DO_TRAVERSAL);
160 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700161 } while (mTraversalScheduled && loopCount > 0);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700162 mWallpaperActionPending = false;
163 }
164
165 private void performSurfacePlacementLoop() {
166 if (mInLayout) {
167 if (DEBUG) {
168 throw new RuntimeException("Recursive call!");
169 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800170 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700171 + Debug.getCallers(3));
172 return;
173 }
174
175 if (mService.mWaitingForConfig) {
176 // Our configuration has changed (most likely rotation), but we
177 // don't yet have the complete configuration to report to
178 // applications. Don't do any window layout until we have it.
179 return;
180 }
181
182 if (!mService.mDisplayReady) {
183 // Not yet initialized, nothing to do.
184 return;
185 }
186
187 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
188 mInLayout = true;
189
190 boolean recoveringMemory = false;
191 if (!mService.mForceRemoves.isEmpty()) {
192 recoveringMemory = true;
193 // Wait a little bit for things to settle down, and off we go.
194 while (!mService.mForceRemoves.isEmpty()) {
195 WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800196 Slog.i(TAG, "Force removing: " + ws);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700197 mService.removeWindowInnerLocked(ws);
198 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800199 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700200 Object tmp = new Object();
201 synchronized (tmp) {
202 try {
203 tmp.wait(250);
204 } catch (InterruptedException e) {
205 }
206 }
207 }
208
209 try {
210 performSurfacePlacementInner(recoveringMemory);
211
212 mInLayout = false;
213
214 if (mService.needsLayout()) {
215 if (++mLayoutRepeatCount < 6) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700216 requestTraversal();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700217 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800218 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700219 mLayoutRepeatCount = 0;
220 }
221 } else {
222 mLayoutRepeatCount = 0;
223 }
224
225 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
226 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
227 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
228 }
229 } catch (RuntimeException e) {
230 mInLayout = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800231 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700232 }
233
234 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
235 }
236
237 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
238 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800239 Slog.v(TAG, "Layouts looping: " + msg +
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700240 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
241 }
242 }
243
244 // "Something has changed! Let's make it correct now."
245 private void performSurfacePlacementInner(boolean recoveringMemory) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800246 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
247 + Debug.getCallers(3));
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700248
249 int i;
250 boolean updateInputWindowsNeeded = false;
251
252 if (mService.mFocusMayChange) {
253 mService.mFocusMayChange = false;
254 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
255 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
256 }
257
258 // Initialize state of exiting tokens.
259 final int numDisplays = mService.mDisplayContents.size();
260 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
261 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
262 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
263 displayContent.mExitingTokens.get(i).hasVisible = false;
264 }
265 }
266
267 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
268 // Initialize state of exiting applications.
269 final AppTokenList exitingAppTokens =
270 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
271 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
272 exitingAppTokens.get(tokenNdx).hasVisible = false;
273 }
274 }
275
276 mHoldScreen = null;
277 mScreenBrightness = -1;
278 mButtonBrightness = -1;
279 mUserActivityTimeout = -1;
280 mObscureApplicationContentOnSecondaryDisplays = false;
281
282 mService.mTransactionSequence++;
283
284 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
285 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
286 final int defaultDw = defaultInfo.logicalWidth;
287 final int defaultDh = defaultInfo.logicalHeight;
288
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800289 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700290 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
291 SurfaceControl.openTransaction();
292 try {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700293 applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700294 } catch (RuntimeException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800295 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700296 } finally {
297 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800298 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700299 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
300 }
301
302 final WindowList defaultWindows = defaultDisplay.getWindowList();
303
304 // If we are ready to perform an app transition, check through
305 // all of the app tokens to be shown and see if they are ready
306 // to go.
307 if (mService.mAppTransition.isReady()) {
308 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
309 if (DEBUG_LAYOUT_REPEATS)
310 debugLayoutRepeats("after handleAppTransitionReadyLocked",
311 defaultDisplay.pendingLayoutChanges);
312 }
313
314 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
315 // We have finished the animation of an app transition. To do
316 // this, we have delayed a lot of operations like showing and
317 // hiding apps, moving apps in Z-order, etc. The app token list
318 // reflects the correct Z-order, but the window list may now
319 // be out of sync with it. So here we will just rebuild the
320 // entire app window list. Fun!
321 defaultDisplay.pendingLayoutChanges |=
322 mService.handleAnimatingStoppedAndTransitionLocked();
323 if (DEBUG_LAYOUT_REPEATS)
324 debugLayoutRepeats("after handleAnimStopAndXitionLock",
325 defaultDisplay.pendingLayoutChanges);
326 }
327
328 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
329 && !mService.mAppTransition.isReady()) {
330 // At this point, there was a window with a wallpaper that
331 // was force hiding other windows behind it, but now it
332 // is going away. This may be simple -- just animate
333 // away the wallpaper and its window -- or it may be
334 // hard -- the wallpaper now needs to be shown behind
335 // something that was hidden.
336 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
337 if (DEBUG_LAYOUT_REPEATS)
338 debugLayoutRepeats("after animateAwayWallpaperLocked",
339 defaultDisplay.pendingLayoutChanges);
340 }
341 mWallpaperForceHidingChanged = false;
342
343 if (mWallpaperMayChange) {
344 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800345 Slog.v(TAG, "Wallpaper may change! Adjusting");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700346 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
347 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
348 defaultDisplay.pendingLayoutChanges);
349 }
350
351 if (mService.mFocusMayChange) {
352 mService.mFocusMayChange = false;
353 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
354 false /*updateInputWindows*/)) {
355 updateInputWindowsNeeded = true;
356 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
357 }
358 }
359
360 if (mService.needsLayout()) {
361 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
362 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
363 defaultDisplay.pendingLayoutChanges);
364 }
365
366 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
367 WindowState win = mService.mResizingWindows.get(i);
368 if (win.mAppFreezing) {
369 // Don't remove this window until rotation has completed.
370 continue;
371 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700372 // Discard the saved surface if window size is changed, it can't be reused.
Chong Zhangbef461f2015-10-27 11:38:24 -0700373 if (win.mAppToken != null) {
374 win.mAppToken.destroySavedSurfaces();
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700375 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700376 win.reportResized();
377 mService.mResizingWindows.remove(i);
378 }
379
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800380 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
381 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700382 if (mOrientationChangeComplete) {
383 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
384 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
385 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
386 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
387 }
388 mService.stopFreezingDisplayLocked();
389 }
390
391 // Destroy the surface of any windows that are no longer visible.
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800392 boolean wallpaperDestroyed = false;
393 i = mService.mDestroySurface.size();
394 if (i > 0) {
395 do {
396 i--;
397 WindowState win = mService.mDestroySurface.get(i);
398 win.mDestroying = false;
399 if (mService.mInputMethodWindow == win) {
400 mService.mInputMethodWindow = null;
401 }
402 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
403 wallpaperDestroyed = true;
404 }
Robert Carr13f7be9e2015-12-02 18:39:45 -0800405 win.destroyOrSaveSurface();
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800406 } while (i > 0);
407 mService.mDestroySurface.clear();
408 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700409
410 // Time to remove any exiting tokens?
411 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
412 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
413 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
414 for (i = exitingTokens.size() - 1; i >= 0; i--) {
415 WindowToken token = exitingTokens.get(i);
416 if (!token.hasVisible) {
417 exitingTokens.remove(i);
418 if (token.windowType == TYPE_WALLPAPER) {
419 mWallpaperControllerLocked.removeWallpaperToken(token);
420 }
421 }
422 }
423 }
424
425 // Time to remove any exiting applications?
426 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
427 // Initialize state of exiting applications.
428 final AppTokenList exitingAppTokens =
429 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
430 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
431 AppWindowToken token = exitingAppTokens.get(i);
432 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
433 (!token.mIsExiting || token.allAppWindows.isEmpty())) {
434 // Make sure there is no animation running on this token,
435 // so any windows associated with it will be removed as
436 // soon as their animations are complete
437 token.mAppAnimator.clearAnimation();
438 token.mAppAnimator.animating = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800439 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
440 "performLayout: App token exiting now removed" + token);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700441 token.removeAppFromTaskLocked();
442 }
443 }
444 }
445
446 if (wallpaperDestroyed) {
447 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
448 defaultDisplay.layoutNeeded = true;
449 }
450
451 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
452 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
453 if (displayContent.pendingLayoutChanges != 0) {
454 displayContent.layoutNeeded = true;
455 }
456 }
457
458 // Finally update all input windows now that the window changes have stabilized.
459 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
460
461 mService.setHoldScreenLocked(mHoldScreen);
462 if (!mService.mDisplayFrozen) {
463 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
464 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
465 } else {
466 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
467 toBrightnessOverride(mScreenBrightness));
468 }
469 if (mButtonBrightness < 0
470 || mButtonBrightness > 1.0f) {
471 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
472 } else {
473 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
474 toBrightnessOverride(mButtonBrightness));
475 }
476 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
477 mUserActivityTimeout);
478 }
479
480 if (mService.mTurnOnScreen) {
481 if (mService.mAllowTheaterModeWakeFromLayout
482 || Settings.Global.getInt(mService.mContext.getContentResolver(),
483 Settings.Global.THEATER_MODE_ON, 0) == 0) {
484 if (DEBUG_VISIBILITY || DEBUG_POWER) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800485 Slog.v(TAG, "Turning screen on after layout!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700486 }
487 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
488 "android.server.wm:TURN_ON");
489 }
490 mService.mTurnOnScreen = false;
491 }
492
493 if (mUpdateRotation) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800494 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700495 if (mService.updateRotationUncheckedLocked(false)) {
496 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
497 } else {
498 mUpdateRotation = false;
499 }
500 }
501
502 if (mService.mWaitingForDrawnCallback != null ||
503 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
504 !mUpdateRotation)) {
505 mService.checkDrawnWindowsLocked();
506 }
507
508 final int N = mService.mPendingRemove.size();
509 if (N > 0) {
510 if (mService.mPendingRemoveTmp.length < N) {
511 mService.mPendingRemoveTmp = new WindowState[N+10];
512 }
513 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
514 mService.mPendingRemove.clear();
515 DisplayContentList displayList = new DisplayContentList();
516 for (i = 0; i < N; i++) {
517 WindowState w = mService.mPendingRemoveTmp[i];
518 mService.removeWindowInnerLocked(w);
519 final DisplayContent displayContent = w.getDisplayContent();
520 if (displayContent != null && !displayList.contains(displayContent)) {
521 displayList.add(displayContent);
522 }
523 }
524
525 for (DisplayContent displayContent : displayList) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800526 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700527 displayContent.layoutNeeded = true;
528 }
529 }
530
531 // Remove all deferred displays stacks, tasks, and activities.
532 for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
533 mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
534 }
535
536 if (updateInputWindowsNeeded) {
537 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
538 }
Chong Zhangb15758a2015-11-17 12:12:03 -0800539 mService.setFocusTaskRegionLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700540
541 // Check to see if we are now in a state where the screen should
542 // be enabled, because the window obscured flags have changed.
543 mService.enableScreenIfNeededLocked();
544
545 mService.scheduleAnimationLocked();
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100546 mService.mWindowPlacerLocked.destroyPendingSurfaces();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700547
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800548 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800549 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700550 }
551
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700552 private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
553 int defaultDw, int defaultDh) {
554 if (mService.mWatermark != null) {
555 mService.mWatermark.positionSurface(defaultDw, defaultDh);
556 }
557 if (mService.mStrictModeFlash != null) {
558 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
559 }
560 if (mService.mCircularDisplayMask != null) {
561 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
562 mService.mRotation);
563 }
564 if (mService.mEmulatorDisplayOverlay != null) {
565 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
566 mService.mRotation);
567 }
568
569 boolean focusDisplayed = false;
570
571 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
572 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
573 boolean updateAllDrawn = false;
574 WindowList windows = displayContent.getWindowList();
575 DisplayInfo displayInfo = displayContent.getDisplayInfo();
576 final int displayId = displayContent.getDisplayId();
577 final int dw = displayInfo.logicalWidth;
578 final int dh = displayInfo.logicalHeight;
579 final int innerDw = displayInfo.appWidth;
580 final int innerDh = displayInfo.appHeight;
581 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
582
583 // Reset for each display.
584 mDisplayHasContent = false;
585 mPreferredRefreshRate = 0;
586 mPreferredModeId = 0;
587
588 int repeats = 0;
589 do {
590 repeats++;
591 if (repeats > 6) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800592 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700593 displayContent.layoutNeeded = false;
594 break;
595 }
596
597 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
598 "On entry to LockedInner", displayContent.pendingLayoutChanges);
599
600 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
601 mWallpaperControllerLocked.adjustWallpaperWindows()) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800602 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700603 displayContent.layoutNeeded = true;
604 }
605
606 if (isDefaultDisplay
607 && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800608 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700609 if (mService.updateOrientationFromAppTokensLocked(true)) {
610 displayContent.layoutNeeded = true;
611 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
612 }
613 }
614
615 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
616 displayContent.layoutNeeded = true;
617 }
618
619 // FIRST LOOP: Perform a layout, if needed.
620 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
621 performLayoutLockedInner(displayContent, repeats == 1,
622 false /* updateInputWindows */);
623 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800624 Slog.w(TAG, "Layout repeat skipped after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700625 }
626
627 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
628 // it is animating.
629 displayContent.pendingLayoutChanges = 0;
630
631 if (isDefaultDisplay) {
632 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
633 for (int i = windows.size() - 1; i >= 0; i--) {
634 WindowState w = windows.get(i);
635 if (w.mHasSurface) {
636 mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
637 w.mAttachedWindow);
638 }
639 }
640 displayContent.pendingLayoutChanges |=
641 mService.mPolicy.finishPostLayoutPolicyLw();
642 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
643 displayContent.pendingLayoutChanges);
644 }
645 } while (displayContent.pendingLayoutChanges != 0);
646
647 mObscured = false;
648 mSyswin = false;
649 displayContent.resetDimming();
650
651 // Only used if default window
652 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
653
654 for (int i = windows.size() - 1; i >= 0; i--) {
655 WindowState w = windows.get(i);
Robert Carr0d00c2e2016-02-29 17:45:02 -0800656 final Task task = w.getTask();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700657 final boolean obscuredChanged = w.mObscured != mObscured;
658
659 // Update effect.
660 w.mObscured = mObscured;
661 if (!mObscured) {
Chong Zhang0abb20f2015-11-19 14:17:31 -0800662 handleNotObscuredLocked(w, displayInfo);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700663 }
664
Chong Zhang112eb8c2015-11-02 11:17:00 -0800665 w.applyDimLayerIfNeeded();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700666
667 if (isDefaultDisplay && obscuredChanged
668 && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
669 // This is the wallpaper target and its obscured state
670 // changed... make sure the current wallaper's visibility
671 // has been updated accordingly.
672 mWallpaperControllerLocked.updateWallpaperVisibility();
673 }
674
675 final WindowStateAnimator winAnimator = w.mWinAnimator;
676
677 // If the window has moved due to its containing content frame changing, then
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800678 // notify the listeners and optionally animate it. Simply checking a change of
679 // position is not enough, because being move due to dock divider is not a trigger
680 // for animation.
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700681 if (w.hasMoved()) {
682 // Frame has moved, containing content frame has also moved, and we're not
683 // currently animating... let's do something.
684 final int left = w.mFrame.left;
685 final int top = w.mFrame.top;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800686 final boolean adjustedForMinimizedDockedStack = w.getTask() != null &&
687 w.getTask().mStack.isAdjustedForMinimizedDockedStack();
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800688 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
Robert Carr0d00c2e2016-02-29 17:45:02 -0800689 && !w.isDragResizing() && !adjustedForMinimizedDockedStack
690 && (task == null || !w.getTask().mStack.getFreezeMovementAnimations())) {
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800691 winAnimator.setMoveAnimation(left, top);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700692 }
693
694 //TODO (multidisplay): Accessibility supported only for the default display.
695 if (mService.mAccessibilityController != null
696 && displayId == Display.DEFAULT_DISPLAY) {
697 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
698 }
699
700 try {
701 w.mClient.moved(left, top);
702 } catch (RemoteException e) {
703 }
704 }
705
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800706 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700707 w.mContentChanged = false;
Chong Zhangbd0d9372015-12-28 15:18:29 -0800708 w.mMovedByResize = false;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700709
710 // Moved from updateWindowsAndWallpaperLocked().
711 if (w.mHasSurface) {
712 // Take care of the window being ready to display.
713 final boolean committed = winAnimator.commitFinishDrawingLocked();
714 if (isDefaultDisplay && committed) {
715 if (w.mAttrs.type == TYPE_DREAM) {
716 // HACK: When a dream is shown, it may at that
717 // point hide the lock screen. So we need to
718 // redo the layout to let the phone window manager
719 // make this happen.
720 displayContent.pendingLayoutChanges |=
721 FINISH_LAYOUT_REDO_LAYOUT;
722 if (DEBUG_LAYOUT_REPEATS) {
723 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
724 displayContent.pendingLayoutChanges);
725 }
726 }
727 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
728 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800729 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700730 mWallpaperMayChange = true;
731 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
732 if (DEBUG_LAYOUT_REPEATS) {
733 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
734 displayContent.pendingLayoutChanges);
735 }
736 }
737 }
Filip Gruszczynskic46f41c2016-01-05 11:29:21 -0800738 if (!winAnimator.isAnimating()) {
739 // Updates the shown frame before we set up the surface. This is needed
740 // because the resizing could change the top-left position (in addition to
741 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
742 // position the surface. We only apply it to windows that aren't animating,
743 // because we depend on the animation to calculate the correct shown frame
744 // on the next animation step.
745 winAnimator.computeShownFrameLocked();
746 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700747 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
748 }
749
750 final AppWindowToken atoken = w.mAppToken;
751 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800752 Slog.d(TAG, "updateWindows: starting " + w
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700753 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
754 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
755 }
756 if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
757 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
758 atoken.lastTransactionSequence = mService.mTransactionSequence;
759 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
760 atoken.startingDisplayed = false;
761 }
762 if ((w.isOnScreenIgnoringKeyguard()
763 || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800764 && !w.mAnimatingExit && !w.mDestroying) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700765 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800766 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700767 + w.isDrawnLw()
768 + ", isAnimating=" + winAnimator.isAnimating());
769 if (!w.isDrawnLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800770 Slog.v(TAG, "Not displayed: s="
Robert Carre6a83512015-11-03 16:09:21 -0800771 + winAnimator.mSurfaceController
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700772 + " pv=" + w.mPolicyVisibility
773 + " mDrawState=" + winAnimator.drawStateToString()
774 + " ah=" + w.mAttachedHidden
775 + " th=" + atoken.hiddenRequested
776 + " a=" + winAnimator.mAnimating);
777 }
778 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800779 if (w != atoken.startingWindow) {
780 if (!w.mAppDied &&
781 (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing)) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700782 atoken.numInterestingWindows++;
783 if (w.isDrawnLw()) {
784 atoken.numDrawnWindows++;
785 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800786 Slog.v(TAG, "tokenMayBeDrawn: " + atoken
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700787 + " freezingScreen="
788 + atoken.mAppAnimator.freezingScreen
789 + " mAppFreezing=" + w.mAppFreezing);
790 updateAllDrawn = true;
791 }
792 }
793 } else if (w.isDrawnLw()) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500794 mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700795 atoken.startingDisplayed = true;
796 }
797 }
798 }
799
800 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
801 && w.isDisplayedLw()) {
802 focusDisplayed = true;
803 }
804
805 mService.updateResizingWindows(w);
806 }
807
808 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
809 mDisplayHasContent,
810 mPreferredRefreshRate,
811 mPreferredModeId,
812 true /* inTraversal, must call performTraversalInTrans... below */);
813
814 mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
815
816 if (updateAllDrawn) {
817 updateAllDrawnLocked(displayContent);
818 }
819 }
820
821 if (focusDisplayed) {
822 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
823 }
824
825 // Give the display manager a chance to adjust properties
826 // like display rotation if it needs to.
827 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
828 }
829
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700830 boolean isInLayout() {
831 return mInLayout;
832 }
833
834 final void performLayoutLockedInner(final DisplayContent displayContent,
835 boolean initial, boolean updateInputWindows) {
836 if (!displayContent.layoutNeeded) {
837 return;
838 }
839 displayContent.layoutNeeded = false;
840 WindowList windows = displayContent.getWindowList();
841 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
842
843 DisplayInfo displayInfo = displayContent.getDisplayInfo();
844 final int dw = displayInfo.logicalWidth;
845 final int dh = displayInfo.logicalHeight;
846
847 if (mService.mInputConsumer != null) {
848 mService.mInputConsumer.layout(dw, dh);
849 }
850
851 final int N = windows.size();
852 int i;
853
854 if (DEBUG_LAYOUT) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800855 Slog.v(TAG, "-------------------------------------");
856 Slog.v(TAG, "performLayout: needed="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700857 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
858 }
859
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800860 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
861 mService.mCurConfiguration.uiMode);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700862 if (isDefaultDisplay) {
863 // Not needed on non-default displays.
864 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
865 mService.mScreenRect.set(0, 0, dw, dh);
866 }
867
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800868 mService.mPolicy.getContentRectLw(mTmpContentRect);
869 displayContent.resize(mTmpContentRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700870
871 int seq = mService.mLayoutSeq+1;
872 if (seq < 0) seq = 0;
873 mService.mLayoutSeq = seq;
874
875 boolean behindDream = false;
876
877 // First perform layout of any root windows (not attached
878 // to another window).
879 int topAttached = -1;
880 for (i = N-1; i >= 0; i--) {
881 final WindowState win = windows.get(i);
882
883 // Don't do layout of a window if it is not visible, or
884 // soon won't be visible, to avoid wasting time and funky
885 // changes while a window is animating away.
886 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
887 || win.isGoneForLayoutLw();
888
889 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800890 Slog.v(TAG, "1ST PASS " + win
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700891 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
892 + " mLayoutAttached=" + win.mLayoutAttached
893 + " screen changed=" + win.isConfigChanged());
894 final AppWindowToken atoken = win.mAppToken;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800895 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700896 + win.mViewVisibility + " mRelayoutCalled="
897 + win.mRelayoutCalled + " hidden="
898 + win.mRootToken.hidden + " hiddenRequested="
899 + (atoken != null && atoken.hiddenRequested)
900 + " mAttachedHidden=" + win.mAttachedHidden);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800901 else Slog.v(TAG, " VIS: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700902 + win.mViewVisibility + " mRelayoutCalled="
903 + win.mRelayoutCalled + " hidden="
904 + win.mRootToken.hidden + " hiddenRequested="
905 + (atoken != null && atoken.hiddenRequested)
906 + " mAttachedHidden=" + win.mAttachedHidden);
907 }
908
909 // If this view is GONE, then skip it -- keep the current
910 // frame, and let the caller know so they can ignore it
911 // if they want. (We do the normal layout for INVISIBLE
912 // windows, since that means "perform layout as normal,
913 // just don't display").
914 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
915 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
916 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
917 (win.mHasSurface && win.mAppToken != null &&
918 win.mAppToken.layoutConfigChanges)))) {
919 if (!win.mLayoutAttached) {
920 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800921 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700922 win.mContentChanged = false;
923 }
924 if (win.mAttrs.type == TYPE_DREAM) {
925 // Don't layout windows behind a dream, so that if it
926 // does stuff like hide the status bar we won't get a
927 // bad transition when it goes away.
928 behindDream = true;
929 }
930 win.mLayoutNeeded = false;
931 win.prelayout();
932 mService.mPolicy.layoutWindowLw(win, null);
933 win.mLayoutSeq = seq;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800934
935 // Window frames may have changed. Update dim layer with the new bounds.
936 final Task task = win.getTask();
937 if (task != null) {
938 displayContent.mDimLayerController.updateDimLayer(task);
939 }
940
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800941 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700942 " LAYOUT: mFrame="
943 + win.mFrame + " mContainingFrame="
944 + win.mContainingFrame + " mDisplayFrame="
945 + win.mDisplayFrame);
946 } else {
947 if (topAttached < 0) topAttached = i;
948 }
949 }
950 }
951
952 boolean attachedBehindDream = false;
953
954 // Now perform layout of attached windows, which usually
955 // depend on the position of the window they are attached to.
956 // XXX does not deal with windows that are attached to windows
957 // that are themselves attached.
958 for (i = topAttached; i >= 0; i--) {
959 final WindowState win = windows.get(i);
960
961 if (win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800962 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700963 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
964 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
965 // If this view is GONE, then skip it -- keep the current
966 // frame, and let the caller know so they can ignore it
967 // if they want. (We do the normal layout for INVISIBLE
968 // windows, since that means "perform layout as normal,
969 // just don't display").
970 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
971 continue;
972 }
973 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
974 || !win.mHaveFrame || win.mLayoutNeeded) {
975 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800976 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700977 win.mContentChanged = false;
978 }
979 win.mLayoutNeeded = false;
980 win.prelayout();
981 mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
982 win.mLayoutSeq = seq;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800983 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700984 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
985 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
986 }
987 } else if (win.mAttrs.type == TYPE_DREAM) {
988 // Don't layout windows behind a dream, so that if it
989 // does stuff like hide the status bar we won't get a
990 // bad transition when it goes away.
991 attachedBehindDream = behindDream;
992 }
993 }
994
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800995 // Window frames may have changed. Tell the input dispatcher about it.
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700996 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
997 if (updateInputWindows) {
998 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
999 }
1000
1001 mService.mPolicy.finishLayoutLw();
Jorim Jaggi61f39a72015-10-29 16:54:18 +01001002 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001003 }
1004
1005 /**
1006 * @param windows List of windows on default display.
1007 * @return bitmap indicating if another pass through layout must be made.
1008 */
1009 private int handleAppTransitionReadyLocked(WindowList windows) {
1010 int appsCount = mService.mOpeningApps.size();
1011 if (!transitionGoodToGo(appsCount)) {
1012 return 0;
1013 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001014 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001015 int transit = mService.mAppTransition.getAppTransition();
1016 if (mService.mSkipAppTransitionAnimation) {
1017 transit = AppTransition.TRANSIT_UNSET;
1018 }
1019 mService.mSkipAppTransitionAnimation = false;
1020 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1021
1022 mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
1023
1024 mService.rebuildAppWindowListLocked();
1025
1026 mWallpaperMayChange = false;
1027
1028 // The top-most window will supply the layout params,
1029 // and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001030 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001031 int bestAnimLayer = -1;
1032 boolean fullscreenAnim = false;
1033 boolean voiceInteraction = false;
1034
1035 final WindowState lowerWallpaperTarget =
1036 mWallpaperControllerLocked.getLowerWallpaperTarget();
1037 final WindowState upperWallpaperTarget =
1038 mWallpaperControllerLocked.getUpperWallpaperTarget();
1039
1040 boolean openingAppHasWallpaper = false;
1041 boolean closingAppHasWallpaper = false;
1042 final AppWindowToken lowerWallpaperAppToken;
1043 final AppWindowToken upperWallpaperAppToken;
1044 if (lowerWallpaperTarget == null) {
1045 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1046 } else {
1047 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1048 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1049 }
1050
1051 int i;
1052 // Do a first pass through the tokens for two
1053 // things:
1054 // (1) Determine if both the closing and opening
1055 // app token sets are wallpaper targets, in which
1056 // case special animations are needed
1057 // (since the wallpaper needs to stay static
1058 // behind them).
1059 // (2) Find the layout params of the top-most
1060 // application window in the tokens, which is
1061 // what will control the animation theme.
1062 final int closingAppsCount = mService.mClosingApps.size();
1063 appsCount = closingAppsCount + mService.mOpeningApps.size();
1064 for (i = 0; i < appsCount; i++) {
1065 final AppWindowToken wtoken;
1066 if (i < closingAppsCount) {
1067 wtoken = mService.mClosingApps.valueAt(i);
1068 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1069 closingAppHasWallpaper = true;
1070 }
1071 } else {
1072 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1073 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1074 openingAppHasWallpaper = true;
1075 }
1076 }
1077
1078 voiceInteraction |= wtoken.voiceInteraction;
1079
1080 if (wtoken.appFullscreen) {
1081 WindowState ws = wtoken.findMainWindow();
1082 if (ws != null) {
1083 animLp = ws.mAttrs;
1084 bestAnimLayer = ws.mLayer;
1085 fullscreenAnim = true;
1086 }
1087 } else if (!fullscreenAnim) {
1088 WindowState ws = wtoken.findMainWindow();
1089 if (ws != null) {
1090 if (ws.mLayer > bestAnimLayer) {
1091 animLp = ws.mAttrs;
1092 bestAnimLayer = ws.mLayer;
1093 }
1094 }
1095 }
1096 }
1097
1098 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1099 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1100
1101 // If all closing windows are obscured, then there is
1102 // no need to do an animation. This is the case, for
1103 // example, when this transition is being done behind
1104 // the lock screen.
1105 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001106 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001107 "Animations disallowed by keyguard or dream.");
1108 animLp = null;
1109 }
1110
1111 processApplicationsAnimatingInPlace(transit);
1112
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001113 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001114 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1115 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1116 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001117
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001118 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1119 animLp, voiceInteraction, topClosingLayer);
1120
1121 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1122 topOpeningApp.mAppAnimator;
1123 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1124 topClosingApp.mAppAnimator;
1125
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001126 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1127 mService.mOpeningApps, mService.mClosingApps);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001128 mService.mAppTransition.postAnimationCallback();
1129 mService.mAppTransition.clear();
1130
1131 mService.mOpeningApps.clear();
1132 mService.mClosingApps.clear();
1133
1134 // This has changed the visibility of windows, so perform
1135 // a new layout to get them all up-to-date.
1136 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1137
1138 // TODO(multidisplay): IMEs are only supported on the default display.
1139 if (windows == mService.getDefaultWindowListLocked()
1140 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001141 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001142 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001143 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1144 true /*updateInputWindows*/);
1145 mService.mFocusMayChange = false;
1146 mService.notifyActivityDrawnForKeyguard();
1147 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1148 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001149
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001150 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1151 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001152 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001153 final int appsCount = mService.mOpeningApps.size();
1154 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001155 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1156 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001157 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001158
1159 if (!appAnimator.usingTransferredAnimation) {
1160 appAnimator.clearThumbnail();
1161 appAnimator.animation = null;
1162 }
1163 wtoken.inPendingTransaction = false;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001164
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001165 if (!mService.setTokenVisibilityLocked(
1166 wtoken, animLp, true, transit, false, voiceInteraction)){
1167 // This token isn't going to be animating. Add it to the list of tokens to
1168 // be notified of app transition complete since the notification will not be
1169 // sent be the app window animator.
1170 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1171 }
1172 wtoken.updateReportedVisibilityLocked();
1173 wtoken.waitingToShow = false;
1174
1175 appAnimator.mAllAppWinAnimators.clear();
1176 final int windowsCount = wtoken.allAppWindows.size();
1177 for (int j = 0; j < windowsCount; j++) {
1178 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1179 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001180 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001181 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1182 SurfaceControl.openTransaction();
1183 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001184 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001185 } finally {
1186 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001187 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001188 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1189 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001190 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1191
1192 int topOpeningLayer = 0;
1193 if (animLp != null) {
1194 int layer = -1;
1195 for (int j = 0; j < wtoken.windows.size(); j++) {
Chong Zhangbef461f2015-10-27 11:38:24 -07001196 final WindowState win = wtoken.windows.get(j);
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001197 // Clearing the mAnimatingExit flag before entering animation. It will be set to true
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001198 // if app window is removed, or window relayout to invisible. We don't want to
1199 // clear it out for windows that get replaced, because the animation depends on
1200 // the flag to remove the replaced window.
Robert Carr7fed68d2016-01-19 21:24:57 -08001201 //
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001202 // We also don't clear the mAnimatingExit flag for windows which have the
Robert Carr7fed68d2016-01-19 21:24:57 -08001203 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
1204 // by the client. We should let animation proceed and not clear this flag or
1205 // they won't eventually be removed by WindowStateAnimator#finishExit.
1206 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001207 win.mAnimatingExit = false;
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001208 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001209 if (win.mWinAnimator.mAnimLayer > layer) {
1210 layer = win.mWinAnimator.mAnimLayer;
1211 }
1212 }
1213 if (topOpeningApp == null || layer > topOpeningLayer) {
1214 topOpeningApp = wtoken;
1215 topOpeningLayer = layer;
1216 }
1217 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001218 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1219 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1220 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001221 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001222 return topOpeningApp;
1223 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001224
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001225 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1226 LayerAndToken layerAndToken) {
1227 final int appsCount;
1228 appsCount = mService.mClosingApps.size();
1229 for (int i = 0; i < appsCount; i++) {
1230 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1231 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001232 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001233 appAnimator.clearThumbnail();
1234 appAnimator.animation = null;
1235 wtoken.inPendingTransaction = false;
1236 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1237 voiceInteraction);
1238 wtoken.updateReportedVisibilityLocked();
1239 // Force the allDrawn flag, because we want to start
1240 // this guy's animations regardless of whether it's
1241 // gotten drawn.
1242 wtoken.allDrawn = true;
1243 wtoken.deferClearAllDrawn = false;
1244 // Ensure that apps that are mid-starting are also scheduled to have their
1245 // starting windows removed after the animation is complete
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001246 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001247 mService.scheduleRemoveStartingWindowLocked(wtoken);
1248 }
1249 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001250
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001251 if (animLp != null) {
1252 int layer = -1;
1253 for (int j = 0; j < wtoken.windows.size(); j++) {
1254 WindowState win = wtoken.windows.get(j);
1255 if (win.mWinAnimator.mAnimLayer > layer) {
1256 layer = win.mWinAnimator.mAnimLayer;
1257 }
1258 }
1259 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1260 layerAndToken.token = wtoken;
1261 layerAndToken.layer = layer;
1262 }
1263 }
1264 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1265 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1266 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001267 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001268 }
1269
1270 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001271 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001272 "Checking " + appsCount + " opening apps (frozen="
1273 + mService.mDisplayFrozen + " timeout="
1274 + mService.mAppTransition.isTimeout() + ")...");
Jorim Jaggi275561a2016-02-23 10:11:02 -05001275 int reason = APP_TRANSITION_TIMEOUT;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001276 if (!mService.mAppTransition.isTimeout()) {
1277 for (int i = 0; i < appsCount; i++) {
1278 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001279 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001280 "Check opening app=" + wtoken + ": allDrawn="
1281 + wtoken.allDrawn + " startingDisplayed="
1282 + wtoken.startingDisplayed + " startingMoved="
Chong Zhangd78ddb42016-03-02 17:01:14 -08001283 + wtoken.startingMoved + " isRelaunching()="
1284 + wtoken.isRelaunching());
1285
1286 if (wtoken.isRelaunching()) {
1287 return false;
1288 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001289
Jorim Jaggi275561a2016-02-23 10:11:02 -05001290 final boolean drawnBeforeRestoring = wtoken.allDrawn;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -08001291 wtoken.restoreSavedSurfaces();
1292
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001293 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1294 return false;
1295 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001296 if (wtoken.allDrawn) {
1297 reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1298 : APP_TRANSITION_SAVED_SURFACE;
1299 } else {
1300 reason = APP_TRANSITION_STARTING_WINDOW;
1301 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001302 }
1303
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001304 // We also need to wait for the specs to be fetched, if needed.
1305 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001306 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001307 return false;
1308 }
1309
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001310 // If the wallpaper is visible, we need to check it's ready too.
Jorim Jaggi275561a2016-02-23 10:11:02 -05001311 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001312 mWallpaperControllerLocked.wallpaperTransitionReady();
Jorim Jaggi275561a2016-02-23 10:11:02 -05001313 if (wallpaperReady) {
1314 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1315 return true;
1316 }
1317 return false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001318 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001319 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001320 return true;
1321 }
1322
1323 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1324 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1325 WindowState upperWallpaperTarget) {
1326 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1327 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1328 final WindowState oldWallpaper =
1329 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1330 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001331 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1332 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001333 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001334 "New wallpaper target=" + wallpaperTarget
1335 + ", oldWallpaper=" + oldWallpaper
1336 + ", lower target=" + lowerWallpaperTarget
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001337 + ", upper target=" + upperWallpaperTarget
1338 + ", openingApps=" + openingApps
1339 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001340 mService.mAnimateWallpaperWithTarget = false;
1341 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1342 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001343 Slog.v(TAG, "Wallpaper animation!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001344 switch (transit) {
1345 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1346 case AppTransition.TRANSIT_TASK_OPEN:
1347 case AppTransition.TRANSIT_TASK_TO_FRONT:
1348 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1349 break;
1350 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1351 case AppTransition.TRANSIT_TASK_CLOSE:
1352 case AppTransition.TRANSIT_TASK_TO_BACK:
1353 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1354 break;
1355 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001356 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001357 "New transit: " + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001358 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1359 && !openingApps.contains(oldWallpaper.mAppToken)
1360 && closingApps.contains(oldWallpaper.mAppToken)) {
1361 // We are transitioning from an activity with a wallpaper to one without.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001362 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001363 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001364 "New transit away from wallpaper: "
1365 + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001366 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1367 openingApps.contains(wallpaperTarget.mAppToken)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001368 // We are transitioning from an activity without
1369 // a wallpaper to now showing the wallpaper
1370 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001371 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001372 "New transit into wallpaper: "
1373 + AppTransition.appTransitionToString(transit));
1374 } else {
1375 mService.mAnimateWallpaperWithTarget = true;
1376 }
1377 return transit;
1378 }
1379
1380 /**
1381 * @param w WindowState this method is applied to.
Chong Zhang0abb20f2015-11-19 14:17:31 -08001382 * @param dispInfo info of the display that the window's obscuring state is checked against.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001383 */
Chong Zhang0abb20f2015-11-19 14:17:31 -08001384 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001385 final LayoutParams attrs = w.mAttrs;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001386 final int attrFlags = attrs.flags;
1387 final boolean canBeSeen = w.isDisplayedLw();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001388
Chong Zhang0abb20f2015-11-19 14:17:31 -08001389 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001390 // This window completely covers everything behind it,
1391 // so we want to leave all of them as undimmed (for
1392 // performance reasons).
1393 mObscured = true;
1394 }
1395
1396 if (w.mHasSurface) {
1397 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1398 mHoldScreen = w.mSession;
1399 }
1400 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1401 && mScreenBrightness < 0) {
1402 mScreenBrightness = w.mAttrs.screenBrightness;
1403 }
1404 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1405 && mButtonBrightness < 0) {
1406 mButtonBrightness = w.mAttrs.buttonBrightness;
1407 }
1408 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1409 && mUserActivityTimeout < 0) {
1410 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1411 }
1412
1413 final int type = attrs.type;
1414 if (canBeSeen
1415 && (type == TYPE_SYSTEM_DIALOG
1416 || type == TYPE_SYSTEM_ERROR
1417 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1418 mSyswin = true;
1419 }
1420
1421 if (canBeSeen) {
1422 // This function assumes that the contents of the default display are
1423 // processed first before secondary displays.
1424 final DisplayContent displayContent = w.getDisplayContent();
1425 if (displayContent != null && displayContent.isDefaultDisplay) {
1426 // While a dream or keyguard is showing, obscure ordinary application
1427 // content on secondary displays (by forcibly enabling mirroring unless
1428 // there is other content we want to show) but still allow opaque
1429 // keyguard dialogs to be shown.
1430 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1431 mObscureApplicationContentOnSecondaryDisplays = true;
1432 }
1433 mDisplayHasContent = true;
1434 } else if (displayContent != null &&
1435 (!mObscureApplicationContentOnSecondaryDisplays
1436 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1437 // Allow full screen keyguard presentation dialogs to be seen.
1438 mDisplayHasContent = true;
1439 }
1440 if (mPreferredRefreshRate == 0
1441 && w.mAttrs.preferredRefreshRate != 0) {
1442 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1443 }
1444 if (mPreferredModeId == 0
1445 && w.mAttrs.preferredDisplayModeId != 0) {
1446 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1447 }
1448 }
1449 }
1450 }
1451
1452 private void updateAllDrawnLocked(DisplayContent displayContent) {
1453 // See if any windows have been drawn, so they (and others
1454 // associated with them) can now be shown.
1455 ArrayList<TaskStack> stacks = displayContent.getStacks();
1456 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1457 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1458 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1459 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1460 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1461 final AppWindowToken wtoken = tokens.get(tokenNdx);
1462 if (!wtoken.allDrawn) {
1463 int numInteresting = wtoken.numInterestingWindows;
1464 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1465 if (DEBUG_VISIBILITY)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001466 Slog.v(TAG, "allDrawn: " + wtoken
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001467 + " interesting=" + numInteresting
1468 + " drawn=" + wtoken.numDrawnWindows);
1469 wtoken.allDrawn = true;
1470 // Force an additional layout pass where WindowStateAnimator#
1471 // commitFinishDrawingLocked() will call performShowLocked().
1472 displayContent.layoutNeeded = true;
1473 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1474 wtoken.token).sendToTarget();
1475 }
1476 }
1477 }
1478 }
1479 }
1480 }
1481
1482 private static int toBrightnessOverride(float value) {
1483 return (int)(value * PowerManager.BRIGHTNESS_ON);
1484 }
1485
1486 private void processApplicationsAnimatingInPlace(int transit) {
1487 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1488 // Find the focused window
1489 final WindowState win = mService.findFocusedWindowLocked(
1490 mService.getDefaultDisplayContentLocked());
1491 if (win != null) {
1492 final AppWindowToken wtoken = win.mAppToken;
1493 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1494 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001495 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001496 appAnimator.clearThumbnail();
1497 appAnimator.animation = null;
1498 mService.updateTokenInPlaceLocked(wtoken, transit);
1499 wtoken.updateReportedVisibilityLocked();
1500
1501 appAnimator.mAllAppWinAnimators.clear();
1502 final int N = wtoken.allAppWindows.size();
1503 for (int j = 0; j < N; j++) {
1504 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1505 }
1506 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001507 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001508 }
1509 }
1510 }
1511
1512 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1513 int openingLayer, int closingLayer) {
1514 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1515 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1516 return;
1517 }
1518 final int taskId = appToken.mTask.mTaskId;
1519 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1520 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001521 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001522 return;
1523 }
1524 // This thumbnail animation is very special, we need to have
1525 // an extra surface with the thumbnail included with the animation.
1526 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1527 try {
1528 // TODO(multi-display): support other displays
1529 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1530 final Display display = displayContent.getDisplay();
1531 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1532
1533 // Create a new surface for the thumbnail
1534 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1535 "thumbnail anim", dirty.width(), dirty.height(),
1536 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1537 surfaceControl.setLayerStack(display.getLayerStack());
1538 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001539 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001540 }
1541
1542 // Draw the thumbnail onto the surface
1543 Surface drawSurface = new Surface();
1544 drawSurface.copyFrom(surfaceControl);
1545 Canvas c = drawSurface.lockCanvas(dirty);
1546 c.drawBitmap(thumbnailHeader, 0, 0, null);
1547 drawSurface.unlockCanvasAndPost(c);
1548 drawSurface.release();
1549
1550 // Get the thumbnail animation
1551 Animation anim;
1552 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1553 // If this is a multi-window scenario, we use the windows frame as
1554 // destination of the thumbnail header animation. If this is a full screen
1555 // window scenario, we use the whole display as the target.
1556 WindowState win = appToken.findMainWindow();
1557 Rect appRect = win != null ? win.getContentFrameLw() :
1558 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1559 // For the new aspect-scaled transition, we want it to always show
1560 // above the animating opening/closing window, and we want to
1561 // synchronize its thumbnail surface with the surface for the
1562 // open/close animation (only on the way down)
1563 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
1564 thumbnailHeader, taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001565 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1566 openingAppAnimator.deferThumbnailDestruction =
1567 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1568 } else {
1569 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1570 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1571 }
1572 anim.restrictDuration(MAX_ANIMATION_DURATION);
1573 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1574
1575 openingAppAnimator.thumbnail = surfaceControl;
1576 openingAppAnimator.thumbnailLayer = openingLayer;
1577 openingAppAnimator.thumbnailAnimation = anim;
1578 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
1579 openingAppAnimator.thumbnailX = mTmpStartRect.left;
1580 openingAppAnimator.thumbnailY = mTmpStartRect.top;
1581 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001582 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001583 + dirty.width() + " h=" + dirty.height(), e);
1584 openingAppAnimator.clearThumbnail();
1585 }
1586 }
1587
1588 boolean copyAnimToLayoutParamsLocked() {
1589 boolean doRequest = false;
1590
1591 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1592 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1593 mUpdateRotation = true;
1594 doRequest = true;
1595 }
1596 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1597 mWallpaperMayChange = true;
1598 doRequest = true;
1599 }
1600 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1601 mWallpaperForceHidingChanged = true;
1602 doRequest = true;
1603 }
1604 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1605 mOrientationChangeComplete = false;
1606 } else {
1607 mOrientationChangeComplete = true;
1608 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1609 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1610 doRequest = true;
1611 }
1612 }
1613 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1614 mService.mTurnOnScreen = true;
1615 }
1616 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1617 mWallpaperActionPending = true;
1618 }
1619
1620 return doRequest;
1621 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001622
1623 void requestTraversal() {
1624 if (!mTraversalScheduled) {
1625 mTraversalScheduled = true;
1626 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1627 }
1628 }
1629
Jorim Jaggi3dac63a2016-03-01 12:37:07 +01001630 /**
1631 * Puts the {@param surface} into a pending list to be destroyed after the current transaction
1632 * has been committed.
1633 */
1634 void destroyAfterTransaction(SurfaceControl surface) {
1635 mPendingDestroyingSurfaces.add(surface);
1636 }
1637
1638 /**
1639 * Destroys any surfaces that have been put into the pending list with
1640 * {@link #destroyAfterTransaction}.
1641 */
1642 void destroyPendingSurfaces() {
1643 for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
1644 mPendingDestroyingSurfaces.get(i).destroy();
1645 }
1646 mPendingDestroyingSurfaces.clear();
1647 }
1648
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001649 public void dump(PrintWriter pw, String prefix) {
1650 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1651 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001652}