1 package com.android.server.wm;
3 import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE;
4 import static android.app.ActivityManagerInternal.APP_TRANSITION_STARTING_WINDOW;
5 import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
6 import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
7 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
8 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
9 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
10 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
11 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
12 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
13 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
14 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
15 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
16 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
17 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
18 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
19 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
20 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
21 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
22 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
23 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
24 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
25 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
26 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
27 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
28 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
29 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
30 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
31 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
32 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
33 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
34 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
35 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
36 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
37 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
38 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
39 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
40 import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
41 import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
42 import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
43 import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
44 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
45 import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
46 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
47 import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
48 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
49 import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
50 import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
51 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
52 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
53 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
55 import android.graphics.Bitmap;
56 import android.graphics.Canvas;
57 import android.graphics.PixelFormat;
58 import android.graphics.Rect;
59 import android.os.Debug;
60 import android.os.PowerManager;
61 import android.os.RemoteException;
62 import android.os.SystemClock;
63 import android.os.Trace;
64 import android.provider.Settings;
65 import android.util.ArraySet;
66 import android.util.Slog;
67 import android.view.Display;
68 import android.view.DisplayInfo;
69 import android.view.Surface;
70 import android.view.SurfaceControl;
71 import android.view.View;
72 import android.view.WindowManager.LayoutParams;
73 import android.view.animation.Animation;
75 import com.android.server.wm.WindowManagerService.H;
77 import java.io.PrintWriter;
78 import java.util.ArrayList;
81 * Positions windows and their surfaces.
83 * It sets positions of windows by calculating their frames and then applies this by positioning
84 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
86 class WindowSurfacePlacer {
87 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
88 private final WindowManagerService mService;
89 private final WallpaperController mWallpaperControllerLocked;
91 private boolean mInLayout = false;
93 /** Only do a maximum of 6 repeated layouts. After that quit */
94 private int mLayoutRepeatCount;
96 static final int SET_UPDATE_ROTATION = 1 << 0;
97 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
98 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
99 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
100 static final int SET_TURN_ON_SCREEN = 1 << 4;
101 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
103 boolean mWallpaperMayChange = false;
104 boolean mOrientationChangeComplete = true;
105 boolean mWallpaperActionPending = false;
107 private boolean mWallpaperForceHidingChanged = false;
108 private Object mLastWindowFreezeSource = null;
109 private Session mHoldScreen = null;
110 private boolean mObscured = false;
111 private boolean mSyswin = false;
112 private float mScreenBrightness = -1;
113 private float mButtonBrightness = -1;
114 private long mUserActivityTimeout = -1;
115 private boolean mUpdateRotation = false;
116 private final Rect mTmpStartRect = new Rect();
117 private final Rect mTmpContentRect = new Rect();
119 // Set to true when the display contains content to show the user.
120 // When false, the display manager may choose to mirror or blank the display.
121 private boolean mDisplayHasContent = false;
123 // Only set while traversing the default display based on its content.
124 // Affects the behavior of mirroring on secondary displays.
125 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
127 private float mPreferredRefreshRate = 0;
129 private int mPreferredModeId = 0;
131 private boolean mTraversalScheduled;
132 private int mDeferDepth = 0;
134 private boolean mSustainedPerformanceModeEnabled = false;
135 private boolean mSustainedPerformanceModeCurrent = false;
137 // Following variables are for debugging screen wakelock only.
138 // Last window that requires screen wakelock
139 WindowState mHoldScreenWindow = null;
140 // Last window that obscures all windows below
141 WindowState mObsuringWindow = null;
143 private static final class LayerAndToken {
145 public AppWindowToken token;
147 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
149 private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
151 public WindowSurfacePlacer(WindowManagerService service) {
153 mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
157 * See {@link WindowManagerService#deferSurfaceLayout()}
164 * See {@link WindowManagerService#continueSurfaceLayout()}
166 void continueLayout() {
168 if (mDeferDepth <= 0) {
169 performSurfacePlacement();
173 final void performSurfacePlacement() {
174 if (mDeferDepth > 0) {
179 mTraversalScheduled = false;
180 performSurfacePlacementLoop();
181 mService.mH.removeMessages(DO_TRAVERSAL);
183 } while (mTraversalScheduled && loopCount > 0);
184 mWallpaperActionPending = false;
187 private void performSurfacePlacementLoop() {
190 throw new RuntimeException("Recursive call!");
192 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
193 + Debug.getCallers(3));
197 if (mService.mWaitingForConfig) {
198 // Our configuration has changed (most likely rotation), but we
199 // don't yet have the complete configuration to report to
200 // applications. Don't do any window layout until we have it.
204 if (!mService.mDisplayReady) {
205 // Not yet initialized, nothing to do.
209 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
212 boolean recoveringMemory = false;
213 if (!mService.mForceRemoves.isEmpty()) {
214 recoveringMemory = true;
215 // Wait a little bit for things to settle down, and off we go.
216 while (!mService.mForceRemoves.isEmpty()) {
217 WindowState ws = mService.mForceRemoves.remove(0);
218 Slog.i(TAG, "Force removing: " + ws);
219 mService.removeWindowInnerLocked(ws);
221 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
222 Object tmp = new Object();
226 } catch (InterruptedException e) {
232 performSurfacePlacementInner(recoveringMemory);
236 if (mService.needsLayout()) {
237 if (++mLayoutRepeatCount < 6) {
240 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
241 mLayoutRepeatCount = 0;
244 mLayoutRepeatCount = 0;
247 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
248 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
249 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
251 } catch (RuntimeException e) {
253 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
256 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
259 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
260 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
261 Slog.v(TAG, "Layouts looping: " + msg +
262 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
266 // "Something has changed! Let's make it correct now."
267 private void performSurfacePlacementInner(boolean recoveringMemory) {
268 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
269 + Debug.getCallers(3));
272 boolean updateInputWindowsNeeded = false;
274 if (mService.mFocusMayChange) {
275 mService.mFocusMayChange = false;
276 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
277 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
280 // Initialize state of exiting tokens.
281 final int numDisplays = mService.mDisplayContents.size();
282 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
283 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
284 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
285 displayContent.mExitingTokens.get(i).hasVisible = false;
289 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
290 // Initialize state of exiting applications.
291 final AppTokenList exitingAppTokens =
292 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
293 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
294 exitingAppTokens.get(tokenNdx).hasVisible = false;
299 mHoldScreenWindow = null;
300 mObsuringWindow = null;
301 mScreenBrightness = -1;
302 mButtonBrightness = -1;
303 mUserActivityTimeout = -1;
304 mObscureApplicationContentOnSecondaryDisplays = false;
305 mSustainedPerformanceModeCurrent = false;
306 mService.mTransactionSequence++;
308 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
309 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
310 final int defaultDw = defaultInfo.logicalWidth;
311 final int defaultDh = defaultInfo.logicalHeight;
313 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
314 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
315 SurfaceControl.openTransaction();
317 applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
318 } catch (RuntimeException e) {
319 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
321 SurfaceControl.closeTransaction();
322 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
323 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
326 final WindowList defaultWindows = defaultDisplay.getWindowList();
328 // If we are ready to perform an app transition, check through
329 // all of the app tokens to be shown and see if they are ready
331 if (mService.mAppTransition.isReady()) {
332 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
333 if (DEBUG_LAYOUT_REPEATS)
334 debugLayoutRepeats("after handleAppTransitionReadyLocked",
335 defaultDisplay.pendingLayoutChanges);
338 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
339 // We have finished the animation of an app transition. To do
340 // this, we have delayed a lot of operations like showing and
341 // hiding apps, moving apps in Z-order, etc. The app token list
342 // reflects the correct Z-order, but the window list may now
343 // be out of sync with it. So here we will just rebuild the
344 // entire app window list. Fun!
345 defaultDisplay.pendingLayoutChanges |=
346 mService.handleAnimatingStoppedAndTransitionLocked();
347 if (DEBUG_LAYOUT_REPEATS)
348 debugLayoutRepeats("after handleAnimStopAndXitionLock",
349 defaultDisplay.pendingLayoutChanges);
352 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
353 && !mService.mAppTransition.isReady()) {
354 // At this point, there was a window with a wallpaper that
355 // was force hiding other windows behind it, but now it
356 // is going away. This may be simple -- just animate
357 // away the wallpaper and its window -- or it may be
358 // hard -- the wallpaper now needs to be shown behind
359 // something that was hidden.
360 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
361 if (DEBUG_LAYOUT_REPEATS)
362 debugLayoutRepeats("after animateAwayWallpaperLocked",
363 defaultDisplay.pendingLayoutChanges);
365 mWallpaperForceHidingChanged = false;
367 if (mWallpaperMayChange) {
368 if (DEBUG_WALLPAPER_LIGHT)
369 Slog.v(TAG, "Wallpaper may change! Adjusting");
370 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
371 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
372 defaultDisplay.pendingLayoutChanges);
375 if (mService.mFocusMayChange) {
376 mService.mFocusMayChange = false;
377 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
378 false /*updateInputWindows*/)) {
379 updateInputWindowsNeeded = true;
380 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
384 if (mService.needsLayout()) {
385 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
386 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
387 defaultDisplay.pendingLayoutChanges);
390 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
391 WindowState win = mService.mResizingWindows.get(i);
392 if (win.mAppFreezing) {
393 // Don't remove this window until rotation has completed.
396 // Discard the saved surface if window size is changed, it can't be reused.
397 if (win.mAppToken != null) {
398 win.mAppToken.destroySavedSurfaces();
401 mService.mResizingWindows.remove(i);
404 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
405 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
406 if (mOrientationChangeComplete) {
407 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
408 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
409 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
410 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
412 mService.stopFreezingDisplayLocked();
415 // Destroy the surface of any windows that are no longer visible.
416 boolean wallpaperDestroyed = false;
417 i = mService.mDestroySurface.size();
421 WindowState win = mService.mDestroySurface.get(i);
422 win.mDestroying = false;
423 if (mService.mInputMethodWindow == win) {
424 mService.mInputMethodWindow = null;
426 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
427 wallpaperDestroyed = true;
429 win.destroyOrSaveSurface();
431 mService.mDestroySurface.clear();
434 // Time to remove any exiting tokens?
435 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
436 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
437 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
438 for (i = exitingTokens.size() - 1; i >= 0; i--) {
439 WindowToken token = exitingTokens.get(i);
440 if (!token.hasVisible) {
441 exitingTokens.remove(i);
442 if (token.windowType == TYPE_WALLPAPER) {
443 mWallpaperControllerLocked.removeWallpaperToken(token);
449 // Time to remove any exiting applications?
450 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
451 // Initialize state of exiting applications.
452 final AppTokenList exitingAppTokens =
453 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
454 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
455 AppWindowToken token = exitingAppTokens.get(i);
456 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
457 (!token.mIsExiting || token.allAppWindows.isEmpty())) {
458 // Make sure there is no animation running on this token,
459 // so any windows associated with it will be removed as
460 // soon as their animations are complete
461 token.mAppAnimator.clearAnimation();
462 token.mAppAnimator.animating = false;
463 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
464 "performLayout: App token exiting now removed" + token);
465 token.removeAppFromTaskLocked();
470 if (wallpaperDestroyed) {
471 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
472 defaultDisplay.layoutNeeded = true;
475 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
476 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
477 if (displayContent.pendingLayoutChanges != 0) {
478 displayContent.layoutNeeded = true;
482 // Finally update all input windows now that the window changes have stabilized.
483 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
485 mService.setHoldScreenLocked(mHoldScreen);
486 if (!mService.mDisplayFrozen) {
487 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
488 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
490 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
491 toBrightnessOverride(mScreenBrightness));
493 if (mButtonBrightness < 0
494 || mButtonBrightness > 1.0f) {
495 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
497 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
498 toBrightnessOverride(mButtonBrightness));
500 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
501 mUserActivityTimeout);
504 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
505 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
506 mService.mPowerManagerInternal.powerHint(
507 mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
508 (mSustainedPerformanceModeEnabled ? 1 : 0));
511 if (mService.mTurnOnScreen) {
512 if (mService.mAllowTheaterModeWakeFromLayout
513 || Settings.Global.getInt(mService.mContext.getContentResolver(),
514 Settings.Global.THEATER_MODE_ON, 0) == 0) {
515 if (DEBUG_VISIBILITY || DEBUG_POWER) {
516 Slog.v(TAG, "Turning screen on after layout!");
518 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
519 "android.server.wm:TURN_ON");
521 mService.mTurnOnScreen = false;
524 if (mUpdateRotation) {
525 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
526 if (mService.updateRotationUncheckedLocked(false)) {
527 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
529 mUpdateRotation = false;
533 if (mService.mWaitingForDrawnCallback != null ||
534 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
536 mService.checkDrawnWindowsLocked();
539 final int N = mService.mPendingRemove.size();
541 if (mService.mPendingRemoveTmp.length < N) {
542 mService.mPendingRemoveTmp = new WindowState[N+10];
544 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
545 mService.mPendingRemove.clear();
546 DisplayContentList displayList = new DisplayContentList();
547 for (i = 0; i < N; i++) {
548 WindowState w = mService.mPendingRemoveTmp[i];
549 mService.removeWindowInnerLocked(w);
550 final DisplayContent displayContent = w.getDisplayContent();
551 if (displayContent != null && !displayList.contains(displayContent)) {
552 displayList.add(displayContent);
556 for (DisplayContent displayContent : displayList) {
557 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
558 displayContent.layoutNeeded = true;
562 // Remove all deferred displays stacks, tasks, and activities.
563 for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
564 mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
567 if (updateInputWindowsNeeded) {
568 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
570 mService.setFocusTaskRegionLocked();
572 // Check to see if we are now in a state where the screen should
573 // be enabled, because the window obscured flags have changed.
574 mService.enableScreenIfNeededLocked();
576 mService.scheduleAnimationLocked();
577 mService.mWindowPlacerLocked.destroyPendingSurfaces();
579 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
580 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
583 private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
584 int defaultDw, int defaultDh) {
585 if (mService.mWatermark != null) {
586 mService.mWatermark.positionSurface(defaultDw, defaultDh);
588 if (mService.mStrictModeFlash != null) {
589 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
591 if (mService.mCircularDisplayMask != null) {
592 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
595 if (mService.mEmulatorDisplayOverlay != null) {
596 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
600 boolean focusDisplayed = false;
602 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
603 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
604 boolean updateAllDrawn = false;
605 WindowList windows = displayContent.getWindowList();
606 DisplayInfo displayInfo = displayContent.getDisplayInfo();
607 final int displayId = displayContent.getDisplayId();
608 final int dw = displayInfo.logicalWidth;
609 final int dh = displayInfo.logicalHeight;
610 final int innerDw = displayInfo.appWidth;
611 final int innerDh = displayInfo.appHeight;
612 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
614 // Reset for each display.
615 mDisplayHasContent = false;
616 mPreferredRefreshRate = 0;
617 mPreferredModeId = 0;
623 Slog.w(TAG, "Animation repeat aborted after too many iterations");
624 displayContent.layoutNeeded = false;
628 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
629 "On entry to LockedInner", displayContent.pendingLayoutChanges);
631 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
632 mWallpaperControllerLocked.adjustWallpaperWindows()) {
633 mService.mLayersController.assignLayersLocked(windows);
634 displayContent.layoutNeeded = true;
638 && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
639 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
640 if (mService.updateOrientationFromAppTokensLocked(true)) {
641 displayContent.layoutNeeded = true;
642 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
646 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
647 displayContent.layoutNeeded = true;
650 // FIRST LOOP: Perform a layout, if needed.
651 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
652 performLayoutLockedInner(displayContent, repeats == 1,
653 false /* updateInputWindows */);
655 Slog.w(TAG, "Layout repeat skipped after too many iterations");
658 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
660 displayContent.pendingLayoutChanges = 0;
662 if (isDefaultDisplay) {
663 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
664 for (int i = windows.size() - 1; i >= 0; i--) {
665 WindowState w = windows.get(i);
667 mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
671 displayContent.pendingLayoutChanges |=
672 mService.mPolicy.finishPostLayoutPolicyLw();
673 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
674 displayContent.pendingLayoutChanges);
676 } while (displayContent.pendingLayoutChanges != 0);
680 displayContent.resetDimming();
682 // Only used if default window
683 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
685 for (int i = windows.size() - 1; i >= 0; i--) {
686 WindowState w = windows.get(i);
687 final Task task = w.getTask();
688 final boolean obscuredChanged = w.mObscured != mObscured;
691 w.mObscured = mObscured;
693 handleNotObscuredLocked(w, displayInfo);
696 w.applyDimLayerIfNeeded();
698 if (isDefaultDisplay && obscuredChanged
699 && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
700 // This is the wallpaper target and its obscured state
701 // changed... make sure the current wallaper's visibility
702 // has been updated accordingly.
703 mWallpaperControllerLocked.updateWallpaperVisibility();
706 final WindowStateAnimator winAnimator = w.mWinAnimator;
708 // If the window has moved due to its containing content frame changing, then
709 // notify the listeners and optionally animate it. Simply checking a change of
710 // position is not enough, because being move due to dock divider is not a trigger
713 // Frame has moved, containing content frame has also moved, and we're not
714 // currently animating... let's do something.
715 final int left = w.mFrame.left;
716 final int top = w.mFrame.top;
717 final boolean adjustedForMinimizedDockOrIme = task != null
718 && (task.mStack.isAdjustedForMinimizedDockedStack()
719 || task.mStack.isAdjustedForIme());
720 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
721 && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
722 && (task == null || w.getTask().mStack.hasMovementAnimations())
723 && !w.mWinAnimator.mLastHidden) {
724 winAnimator.setMoveAnimation(left, top);
727 //TODO (multidisplay): Accessibility supported only for the default display.
728 if (mService.mAccessibilityController != null
729 && displayId == Display.DEFAULT_DISPLAY) {
730 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
734 w.mClient.moved(left, top);
735 } catch (RemoteException e) {
737 w.mMovedByResize = false;
740 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
741 w.mContentChanged = false;
743 // Moved from updateWindowsAndWallpaperLocked().
745 // If we have recently synchronized a previous transaction for this
746 // window ensure we don't push through an unsynchronized one now.
747 winAnimator.deferToPendingTransaction();
749 // Take care of the window being ready to display.
750 final boolean committed = winAnimator.commitFinishDrawingLocked();
751 if (isDefaultDisplay && committed) {
752 if (w.mAttrs.type == TYPE_DREAM) {
753 // HACK: When a dream is shown, it may at that
754 // point hide the lock screen. So we need to
755 // redo the layout to let the phone window manager
757 displayContent.pendingLayoutChanges |=
758 FINISH_LAYOUT_REDO_LAYOUT;
759 if (DEBUG_LAYOUT_REPEATS) {
760 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
761 displayContent.pendingLayoutChanges);
764 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
765 if (DEBUG_WALLPAPER_LIGHT)
766 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
767 mWallpaperMayChange = true;
768 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
769 if (DEBUG_LAYOUT_REPEATS) {
770 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
771 displayContent.pendingLayoutChanges);
775 if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
776 // Updates the shown frame before we set up the surface. This is needed
777 // because the resizing could change the top-left position (in addition to
778 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
779 // position the surface.
781 // If an animation is being started, we can't call this method because the
782 // animation hasn't processed its initial transformation yet, but in general
783 // we do want to update the position if the window is animating.
784 winAnimator.computeShownFrameLocked();
786 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
789 final AppWindowToken atoken = w.mAppToken;
790 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
791 Slog.d(TAG, "updateWindows: starting " + w
792 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
793 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
795 if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
796 || atoken.mAppAnimator.freezingScreen)) {
797 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
798 atoken.lastTransactionSequence = mService.mTransactionSequence;
799 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
800 atoken.numInterestingWindowsExcludingSaved = 0;
801 atoken.numDrawnWindowsExclusingSaved = 0;
802 atoken.startingDisplayed = false;
804 if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
805 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
806 Slog.v(TAG, "Eval win " + w + ": isDrawn="
808 + ", isAnimationSet=" + winAnimator.isAnimationSet());
809 if (!w.isDrawnLw()) {
810 Slog.v(TAG, "Not displayed: s="
811 + winAnimator.mSurfaceController
812 + " pv=" + w.mPolicyVisibility
813 + " mDrawState=" + winAnimator.drawStateToString()
814 + " ah=" + w.mAttachedHidden
815 + " th=" + atoken.hiddenRequested
816 + " a=" + winAnimator.mAnimating);
819 if (w != atoken.startingWindow) {
820 if (w.isInteresting()) {
821 atoken.numInterestingWindows++;
823 atoken.numDrawnWindows++;
824 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
825 Slog.v(TAG, "tokenMayBeDrawn: " + atoken
826 + " w=" + w + " numInteresting="
827 + atoken.numInterestingWindows
829 + atoken.mAppAnimator.freezingScreen
830 + " mAppFreezing=" + w.mAppFreezing);
831 updateAllDrawn = true;
834 } else if (w.isDrawnLw()) {
835 mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
836 atoken.startingDisplayed = true;
839 if (!atoken.allDrawnExcludingSaved
840 && w.mightAffectAllDrawn(true /* visibleOnly */)) {
841 if (w != atoken.startingWindow && w.isInteresting()) {
842 atoken.numInterestingWindowsExcludingSaved++;
843 if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
844 atoken.numDrawnWindowsExclusingSaved++;
845 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
846 Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
847 + " w=" + w + " numInteresting="
848 + atoken.numInterestingWindowsExcludingSaved
850 + atoken.mAppAnimator.freezingScreen
851 + " mAppFreezing=" + w.mAppFreezing);
852 updateAllDrawn = true;
858 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
859 && w.isDisplayedLw()) {
860 focusDisplayed = true;
863 mService.updateResizingWindows(w);
866 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
868 mPreferredRefreshRate,
870 true /* inTraversal, must call performTraversalInTrans... below */);
872 mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
874 if (updateAllDrawn) {
875 updateAllDrawnLocked(displayContent);
879 if (focusDisplayed) {
880 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
883 // Give the display manager a chance to adjust properties
884 // like display rotation if it needs to.
885 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
888 boolean isInLayout() {
892 final void performLayoutLockedInner(final DisplayContent displayContent,
893 boolean initial, boolean updateInputWindows) {
894 if (!displayContent.layoutNeeded) {
897 displayContent.layoutNeeded = false;
898 WindowList windows = displayContent.getWindowList();
899 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
901 DisplayInfo displayInfo = displayContent.getDisplayInfo();
902 final int dw = displayInfo.logicalWidth;
903 final int dh = displayInfo.logicalHeight;
905 if (mService.mInputConsumer != null) {
906 mService.mInputConsumer.layout(dw, dh);
909 if (mService.mWallpaperInputConsumer != null) {
910 mService.mWallpaperInputConsumer.layout(dw, dh);
913 final int N = windows.size();
917 Slog.v(TAG, "-------------------------------------");
918 Slog.v(TAG, "performLayout: needed="
919 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
922 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
923 mService.mCurConfiguration.uiMode);
924 if (isDefaultDisplay) {
925 // Not needed on non-default displays.
926 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
927 mService.mScreenRect.set(0, 0, dw, dh);
930 mService.mPolicy.getContentRectLw(mTmpContentRect);
931 displayContent.resize(mTmpContentRect);
933 int seq = mService.mLayoutSeq+1;
934 if (seq < 0) seq = 0;
935 mService.mLayoutSeq = seq;
937 boolean behindDream = false;
939 // First perform layout of any root windows (not attached
940 // to another window).
941 int topAttached = -1;
942 for (i = N-1; i >= 0; i--) {
943 final WindowState win = windows.get(i);
945 // Don't do layout of a window if it is not visible, or
946 // soon won't be visible, to avoid wasting time and funky
947 // changes while a window is animating away.
948 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
949 || win.isGoneForLayoutLw();
951 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
952 Slog.v(TAG, "1ST PASS " + win
953 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
954 + " mLayoutAttached=" + win.mLayoutAttached
955 + " screen changed=" + win.isConfigChanged());
956 final AppWindowToken atoken = win.mAppToken;
957 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
958 + win.mViewVisibility + " mRelayoutCalled="
959 + win.mRelayoutCalled + " hidden="
960 + win.mRootToken.hidden + " hiddenRequested="
961 + (atoken != null && atoken.hiddenRequested)
962 + " mAttachedHidden=" + win.mAttachedHidden);
963 else Slog.v(TAG, " VIS: mViewVisibility="
964 + win.mViewVisibility + " mRelayoutCalled="
965 + win.mRelayoutCalled + " hidden="
966 + win.mRootToken.hidden + " hiddenRequested="
967 + (atoken != null && atoken.hiddenRequested)
968 + " mAttachedHidden=" + win.mAttachedHidden);
971 // If this view is GONE, then skip it -- keep the current
972 // frame, and let the caller know so they can ignore it
973 // if they want. (We do the normal layout for INVISIBLE
974 // windows, since that means "perform layout as normal,
975 // just don't display").
976 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
977 || ((win.isConfigChanged() || win.setReportResizeHints())
978 && !win.isGoneForLayoutLw() &&
979 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
980 (win.mHasSurface && win.mAppToken != null &&
981 win.mAppToken.layoutConfigChanges)))) {
982 if (!win.mLayoutAttached) {
984 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
985 win.mContentChanged = false;
987 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.
993 win.mLayoutNeeded = false;
995 mService.mPolicy.layoutWindowLw(win, null);
996 win.mLayoutSeq = seq;
998 // Window frames may have changed. Update dim layer with the new bounds.
999 final Task task = win.getTask();
1001 displayContent.mDimLayerController.updateDimLayer(task);
1004 if (DEBUG_LAYOUT) Slog.v(TAG,
1006 + win.mFrame + " mContainingFrame="
1007 + win.mContainingFrame + " mDisplayFrame="
1008 + win.mDisplayFrame);
1010 if (topAttached < 0) topAttached = i;
1015 boolean attachedBehindDream = false;
1017 // Now perform layout of attached windows, which usually
1018 // depend on the position of the window they are attached to.
1019 // XXX does not deal with windows that are attached to windows
1020 // that are themselves attached.
1021 for (i = topAttached; i >= 0; i--) {
1022 final WindowState win = windows.get(i);
1024 if (win.mLayoutAttached) {
1025 if (DEBUG_LAYOUT) Slog.v(TAG,
1026 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
1027 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
1028 // If this view is GONE, then skip it -- keep the current
1029 // frame, and let the caller know so they can ignore it
1030 // if they want. (We do the normal layout for INVISIBLE
1031 // windows, since that means "perform layout as normal,
1032 // just don't display").
1033 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
1036 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
1037 || !win.mHaveFrame || win.mLayoutNeeded) {
1039 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
1040 win.mContentChanged = false;
1042 win.mLayoutNeeded = false;
1044 mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
1045 win.mLayoutSeq = seq;
1046 if (DEBUG_LAYOUT) Slog.v(TAG,
1047 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
1048 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
1050 } else if (win.mAttrs.type == TYPE_DREAM) {
1051 // Don't layout windows behind a dream, so that if it
1052 // does stuff like hide the status bar we won't get a
1053 // bad transition when it goes away.
1054 attachedBehindDream = behindDream;
1058 // Window frames may have changed. Tell the input dispatcher about it.
1059 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
1060 if (updateInputWindows) {
1061 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
1064 mService.mPolicy.finishLayoutLw();
1065 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
1069 * @param windows List of windows on default display.
1070 * @return bitmap indicating if another pass through layout must be made.
1072 private int handleAppTransitionReadyLocked(WindowList windows) {
1073 int appsCount = mService.mOpeningApps.size();
1074 if (!transitionGoodToGo(appsCount)) {
1077 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
1079 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
1080 int transit = mService.mAppTransition.getAppTransition();
1081 if (mService.mSkipAppTransitionAnimation) {
1082 transit = AppTransition.TRANSIT_UNSET;
1084 mService.mSkipAppTransitionAnimation = false;
1085 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1087 mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
1089 mService.rebuildAppWindowListLocked();
1091 mWallpaperMayChange = false;
1093 // The top-most window will supply the layout params,
1094 // and we will determine it below.
1095 LayoutParams animLp = null;
1096 int bestAnimLayer = -1;
1097 boolean fullscreenAnim = false;
1098 boolean voiceInteraction = false;
1100 final WindowState lowerWallpaperTarget =
1101 mWallpaperControllerLocked.getLowerWallpaperTarget();
1102 final WindowState upperWallpaperTarget =
1103 mWallpaperControllerLocked.getUpperWallpaperTarget();
1105 boolean openingAppHasWallpaper = false;
1106 boolean closingAppHasWallpaper = false;
1107 final AppWindowToken lowerWallpaperAppToken;
1108 final AppWindowToken upperWallpaperAppToken;
1109 if (lowerWallpaperTarget == null) {
1110 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1112 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1113 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1117 // Do a first pass through the tokens for two
1119 // (1) Determine if both the closing and opening
1120 // app token sets are wallpaper targets, in which
1121 // case special animations are needed
1122 // (since the wallpaper needs to stay static
1124 // (2) Find the layout params of the top-most
1125 // application window in the tokens, which is
1126 // what will control the animation theme.
1127 final int closingAppsCount = mService.mClosingApps.size();
1128 appsCount = closingAppsCount + mService.mOpeningApps.size();
1129 for (i = 0; i < appsCount; i++) {
1130 final AppWindowToken wtoken;
1131 if (i < closingAppsCount) {
1132 wtoken = mService.mClosingApps.valueAt(i);
1133 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1134 closingAppHasWallpaper = true;
1137 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1138 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1139 openingAppHasWallpaper = true;
1143 voiceInteraction |= wtoken.voiceInteraction;
1145 if (wtoken.appFullscreen) {
1146 WindowState ws = wtoken.findMainWindow();
1149 bestAnimLayer = ws.mLayer;
1150 fullscreenAnim = true;
1152 } else if (!fullscreenAnim) {
1153 WindowState ws = wtoken.findMainWindow();
1155 if (ws.mLayer > bestAnimLayer) {
1157 bestAnimLayer = ws.mLayer;
1163 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1164 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1166 // If all closing windows are obscured, then there is
1167 // no need to do an animation. This is the case, for
1168 // example, when this transition is being done behind
1170 if (!mService.mPolicy.allowAppAnimationsLw()) {
1171 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1172 "Animations disallowed by keyguard or dream.");
1176 processApplicationsAnimatingInPlace(transit);
1178 mTmpLayerAndToken.token = null;
1179 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1180 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1181 final int topClosingLayer = mTmpLayerAndToken.layer;
1183 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1184 animLp, voiceInteraction, topClosingLayer);
1186 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1187 topOpeningApp.mAppAnimator;
1188 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1189 topClosingApp.mAppAnimator;
1191 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1192 mService.mOpeningApps, mService.mClosingApps);
1193 mService.mAppTransition.postAnimationCallback();
1194 mService.mAppTransition.clear();
1196 mService.mOpeningApps.clear();
1197 mService.mClosingApps.clear();
1199 // This has changed the visibility of windows, so perform
1200 // a new layout to get them all up-to-date.
1201 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1203 // TODO(multidisplay): IMEs are only supported on the default display.
1204 if (windows == mService.getDefaultWindowListLocked()
1205 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
1206 mService.mLayersController.assignLayersLocked(windows);
1208 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1209 true /*updateInputWindows*/);
1210 mService.mFocusMayChange = false;
1211 mService.notifyActivityDrawnForKeyguard();
1213 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1215 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1218 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1219 boolean voiceInteraction, int topClosingLayer) {
1220 AppWindowToken topOpeningApp = null;
1221 final int appsCount = mService.mOpeningApps.size();
1222 for (int i = 0; i < appsCount; i++) {
1223 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1224 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1225 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
1227 if (!appAnimator.usingTransferredAnimation) {
1228 appAnimator.clearThumbnail();
1229 appAnimator.setNullAnimation();
1231 wtoken.inPendingTransaction = false;
1233 if (!mService.setTokenVisibilityLocked(
1234 wtoken, animLp, true, transit, false, voiceInteraction)){
1235 // This token isn't going to be animating. Add it to the list of tokens to
1236 // be notified of app transition complete since the notification will not be
1237 // sent be the app window animator.
1238 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1240 wtoken.updateReportedVisibilityLocked();
1241 wtoken.waitingToShow = false;
1243 appAnimator.mAllAppWinAnimators.clear();
1244 final int windowsCount = wtoken.allAppWindows.size();
1245 for (int j = 0; j < windowsCount; j++) {
1246 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1248 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1249 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1250 SurfaceControl.openTransaction();
1252 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
1254 SurfaceControl.closeTransaction();
1255 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1256 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1258 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1260 int topOpeningLayer = 0;
1261 if (animLp != null) {
1263 for (int j = 0; j < wtoken.allAppWindows.size(); j++) {
1264 final WindowState win = wtoken.allAppWindows.get(j);
1265 // Clearing the mAnimatingExit flag before entering animation. It will be set to true
1266 // if app window is removed, or window relayout to invisible. We don't want to
1267 // clear it out for windows that get replaced, because the animation depends on
1268 // the flag to remove the replaced window.
1270 // We also don't clear the mAnimatingExit flag for windows which have the
1271 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
1272 // by the client. We should let animation proceed and not clear this flag or
1273 // they won't eventually be removed by WindowStateAnimator#finishExit.
1274 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
1275 win.mAnimatingExit = false;
1276 // Clear mAnimating flag together with mAnimatingExit. When animation
1277 // changes from exiting to entering, we need to clear this flag until the
1278 // new animation gets applied, so that isAnimationStarting() becomes true
1280 // Otherwise applySurfaceChangesTransaction will faill to skip surface
1281 // placement for this window during this period, one or more frame will
1282 // show up with wrong position or scale.
1283 win.mWinAnimator.mAnimating = false;
1285 if (win.mWinAnimator.mAnimLayer > layer) {
1286 layer = win.mWinAnimator.mAnimLayer;
1289 if (topOpeningApp == null || layer > topOpeningLayer) {
1290 topOpeningApp = wtoken;
1291 topOpeningLayer = layer;
1294 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1295 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1298 return topOpeningApp;
1301 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1302 LayerAndToken layerAndToken) {
1303 final int appsCount;
1304 appsCount = mService.mClosingApps.size();
1305 for (int i = 0; i < appsCount; i++) {
1306 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1308 // If we still have some windows animating with saved surfaces that's
1309 // either invisible or already removed, mark them exiting so that they
1310 // are disposed of after the exit animation. These are not supposed to
1311 // be shown, or are delayed removal until app is actually drawn (in which
1312 // case the window will be removed after the animation).
1313 wtoken.markSavedSurfaceExiting();
1315 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1316 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
1317 appAnimator.clearThumbnail();
1318 appAnimator.setNullAnimation();
1319 wtoken.inPendingTransaction = false;
1320 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1322 wtoken.updateReportedVisibilityLocked();
1323 // Force the allDrawn flag, because we want to start
1324 // this guy's animations regardless of whether it's
1326 wtoken.allDrawn = true;
1327 wtoken.deferClearAllDrawn = false;
1328 // Ensure that apps that are mid-starting are also scheduled to have their
1329 // starting windows removed after the animation is complete
1330 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
1331 mService.scheduleRemoveStartingWindowLocked(wtoken);
1333 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1335 if (animLp != null) {
1337 for (int j = 0; j < wtoken.windows.size(); j++) {
1338 WindowState win = wtoken.windows.get(j);
1339 if (win.mWinAnimator.mAnimLayer > layer) {
1340 layer = win.mWinAnimator.mAnimLayer;
1343 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1344 layerAndToken.token = wtoken;
1345 layerAndToken.layer = layer;
1348 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1349 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1354 private boolean transitionGoodToGo(int appsCount) {
1355 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1356 "Checking " + appsCount + " opening apps (frozen="
1357 + mService.mDisplayFrozen + " timeout="
1358 + mService.mAppTransition.isTimeout() + ")...");
1359 int reason = APP_TRANSITION_TIMEOUT;
1360 if (!mService.mAppTransition.isTimeout()) {
1361 for (int i = 0; i < appsCount; i++) {
1362 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1363 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1364 "Check opening app=" + wtoken + ": allDrawn="
1365 + wtoken.allDrawn + " startingDisplayed="
1366 + wtoken.startingDisplayed + " startingMoved="
1367 + wtoken.startingMoved + " isRelaunching()="
1368 + wtoken.isRelaunching());
1370 if (wtoken.isRelaunching()) {
1374 final boolean drawnBeforeRestoring = wtoken.allDrawn;
1375 wtoken.restoreSavedSurfaces();
1377 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1380 if (wtoken.allDrawn) {
1381 reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1382 : APP_TRANSITION_SAVED_SURFACE;
1384 reason = APP_TRANSITION_STARTING_WINDOW;
1388 // We also need to wait for the specs to be fetched, if needed.
1389 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
1390 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
1394 // If the wallpaper is visible, we need to check it's ready too.
1395 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
1396 mWallpaperControllerLocked.wallpaperTransitionReady();
1397 if (wallpaperReady) {
1398 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1403 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1407 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1408 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1409 WindowState upperWallpaperTarget) {
1410 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1411 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1412 final WindowState oldWallpaper =
1413 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1414 ? null : wallpaperTarget;
1415 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1416 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
1417 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1418 "New wallpaper target=" + wallpaperTarget
1419 + ", oldWallpaper=" + oldWallpaper
1420 + ", lower target=" + lowerWallpaperTarget
1421 + ", upper target=" + upperWallpaperTarget
1422 + ", openingApps=" + openingApps
1423 + ", closingApps=" + closingApps);
1424 mService.mAnimateWallpaperWithTarget = false;
1425 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1426 if (DEBUG_APP_TRANSITIONS)
1427 Slog.v(TAG, "Wallpaper animation!");
1429 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1430 case AppTransition.TRANSIT_TASK_OPEN:
1431 case AppTransition.TRANSIT_TASK_TO_FRONT:
1432 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1434 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1435 case AppTransition.TRANSIT_TASK_CLOSE:
1436 case AppTransition.TRANSIT_TASK_TO_BACK:
1437 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1440 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1441 "New transit: " + AppTransition.appTransitionToString(transit));
1442 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1443 && !openingApps.contains(oldWallpaper.mAppToken)
1444 && closingApps.contains(oldWallpaper.mAppToken)) {
1445 // We are transitioning from an activity with a wallpaper to one without.
1446 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
1447 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1448 "New transit away from wallpaper: "
1449 + AppTransition.appTransitionToString(transit));
1450 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1451 openingApps.contains(wallpaperTarget.mAppToken)) {
1452 // We are transitioning from an activity without
1453 // a wallpaper to now showing the wallpaper
1454 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
1455 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1456 "New transit into wallpaper: "
1457 + AppTransition.appTransitionToString(transit));
1459 mService.mAnimateWallpaperWithTarget = true;
1465 * @param w WindowState this method is applied to.
1466 * @param dispInfo info of the display that the window's obscuring state is checked against.
1468 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
1469 final LayoutParams attrs = w.mAttrs;
1470 final int attrFlags = attrs.flags;
1471 final boolean canBeSeen = w.isDisplayedLw();
1472 final int privateflags = attrs.privateFlags;
1474 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
1475 // This window completely covers everything behind it,
1476 // so we want to leave all of them as undimmed (for
1477 // performance reasons).
1479 mObsuringWindow = w;
1485 if (w.mHasSurface) {
1486 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1487 mHoldScreen = w.mSession;
1488 mHoldScreenWindow = w;
1489 } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
1490 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
1491 + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
1492 + Debug.getCallers(10));
1494 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1495 && mScreenBrightness < 0) {
1496 mScreenBrightness = w.mAttrs.screenBrightness;
1498 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1499 && mButtonBrightness < 0) {
1500 mButtonBrightness = w.mAttrs.buttonBrightness;
1502 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1503 && mUserActivityTimeout < 0) {
1504 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1507 final int type = attrs.type;
1509 && (type == TYPE_SYSTEM_DIALOG
1510 || type == TYPE_SYSTEM_ERROR
1511 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1516 // This function assumes that the contents of the default display are
1517 // processed first before secondary displays.
1518 final DisplayContent displayContent = w.getDisplayContent();
1519 if (displayContent != null && displayContent.isDefaultDisplay) {
1520 // While a dream or keyguard is showing, obscure ordinary application
1521 // content on secondary displays (by forcibly enabling mirroring unless
1522 // there is other content we want to show) but still allow opaque
1523 // keyguard dialogs to be shown.
1524 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1525 mObscureApplicationContentOnSecondaryDisplays = true;
1527 mDisplayHasContent = true;
1528 } else if (displayContent != null &&
1529 (!mObscureApplicationContentOnSecondaryDisplays
1530 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1531 // Allow full screen keyguard presentation dialogs to be seen.
1532 mDisplayHasContent = true;
1534 if (mPreferredRefreshRate == 0
1535 && w.mAttrs.preferredRefreshRate != 0) {
1536 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1538 if (mPreferredModeId == 0
1539 && w.mAttrs.preferredDisplayModeId != 0) {
1540 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1542 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1543 mSustainedPerformanceModeCurrent = true;
1549 private void updateAllDrawnLocked(DisplayContent displayContent) {
1550 // See if any windows have been drawn, so they (and others
1551 // associated with them) can now be shown.
1552 ArrayList<TaskStack> stacks = displayContent.getStacks();
1553 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1554 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1555 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1556 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1557 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1558 final AppWindowToken wtoken = tokens.get(tokenNdx);
1559 if (!wtoken.allDrawn) {
1560 int numInteresting = wtoken.numInterestingWindows;
1561 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1562 if (DEBUG_VISIBILITY)
1563 Slog.v(TAG, "allDrawn: " + wtoken
1564 + " interesting=" + numInteresting
1565 + " drawn=" + wtoken.numDrawnWindows);
1566 wtoken.allDrawn = true;
1567 // Force an additional layout pass where WindowStateAnimator#
1568 // commitFinishDrawingLocked() will call performShowLocked().
1569 displayContent.layoutNeeded = true;
1570 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1571 wtoken.token).sendToTarget();
1574 if (!wtoken.allDrawnExcludingSaved) {
1575 int numInteresting = wtoken.numInterestingWindowsExcludingSaved;
1576 if (numInteresting > 0
1577 && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) {
1578 if (DEBUG_VISIBILITY)
1579 Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken
1580 + " interesting=" + numInteresting
1581 + " drawn=" + wtoken.numDrawnWindowsExclusingSaved);
1582 wtoken.allDrawnExcludingSaved = true;
1583 displayContent.layoutNeeded = true;
1584 if (wtoken.isAnimatingInvisibleWithSavedSurface()
1585 && !mService.mFinishedEarlyAnim.contains(wtoken)) {
1586 mService.mFinishedEarlyAnim.add(wtoken);
1595 private static int toBrightnessOverride(float value) {
1596 return (int)(value * PowerManager.BRIGHTNESS_ON);
1599 private void processApplicationsAnimatingInPlace(int transit) {
1600 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1601 // Find the focused window
1602 final WindowState win = mService.findFocusedWindowLocked(
1603 mService.getDefaultDisplayContentLocked());
1605 final AppWindowToken wtoken = win.mAppToken;
1606 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1607 if (DEBUG_APP_TRANSITIONS)
1608 Slog.v(TAG, "Now animating app in place " + wtoken);
1609 appAnimator.clearThumbnail();
1610 appAnimator.setNullAnimation();
1611 mService.updateTokenInPlaceLocked(wtoken, transit);
1612 wtoken.updateReportedVisibilityLocked();
1614 appAnimator.mAllAppWinAnimators.clear();
1615 final int N = wtoken.allAppWindows.size();
1616 for (int j = 0; j < N; j++) {
1617 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1619 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1620 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
1625 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1626 int openingLayer, int closingLayer) {
1627 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1628 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1631 final int taskId = appToken.mTask.mTaskId;
1632 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1633 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
1634 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
1637 // This thumbnail animation is very special, we need to have
1638 // an extra surface with the thumbnail included with the animation.
1639 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1641 // TODO(multi-display): support other displays
1642 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1643 final Display display = displayContent.getDisplay();
1644 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1646 // Create a new surface for the thumbnail
1647 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1648 "thumbnail anim", dirty.width(), dirty.height(),
1649 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1650 surfaceControl.setLayerStack(display.getLayerStack());
1651 if (SHOW_TRANSACTIONS) {
1652 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
1655 // Draw the thumbnail onto the surface
1656 Surface drawSurface = new Surface();
1657 drawSurface.copyFrom(surfaceControl);
1658 Canvas c = drawSurface.lockCanvas(dirty);
1659 c.drawBitmap(thumbnailHeader, 0, 0, null);
1660 drawSurface.unlockCanvasAndPost(c);
1661 drawSurface.release();
1663 // Get the thumbnail animation
1665 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1666 // If this is a multi-window scenario, we use the windows frame as
1667 // destination of the thumbnail header animation. If this is a full screen
1668 // window scenario, we use the whole display as the target.
1669 WindowState win = appToken.findMainWindow();
1670 Rect appRect = win != null ? win.getContentFrameLw() :
1671 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1672 Rect insets = win != null ? win.mContentInsets : null;
1673 // For the new aspect-scaled transition, we want it to always show
1674 // above the animating opening/closing window, and we want to
1675 // synchronize its thumbnail surface with the surface for the
1676 // open/close animation (only on the way down)
1677 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
1678 insets, thumbnailHeader, taskId, mService.mCurConfiguration.uiMode,
1679 mService.mCurConfiguration.orientation);
1680 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1681 openingAppAnimator.deferThumbnailDestruction =
1682 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1684 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1685 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1687 anim.restrictDuration(MAX_ANIMATION_DURATION);
1688 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1690 openingAppAnimator.thumbnail = surfaceControl;
1691 openingAppAnimator.thumbnailLayer = openingLayer;
1692 openingAppAnimator.thumbnailAnimation = anim;
1693 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
1694 } catch (Surface.OutOfResourcesException e) {
1695 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
1696 + dirty.width() + " h=" + dirty.height(), e);
1697 openingAppAnimator.clearThumbnail();
1701 boolean copyAnimToLayoutParamsLocked() {
1702 boolean doRequest = false;
1704 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1705 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1706 mUpdateRotation = true;
1709 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1710 mWallpaperMayChange = true;
1713 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1714 mWallpaperForceHidingChanged = true;
1717 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1718 mOrientationChangeComplete = false;
1720 mOrientationChangeComplete = true;
1721 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1722 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1726 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1727 mService.mTurnOnScreen = true;
1729 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1730 mWallpaperActionPending = true;
1736 void requestTraversal() {
1737 if (!mTraversalScheduled) {
1738 mTraversalScheduled = true;
1739 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1744 * Puts the {@param surface} into a pending list to be destroyed after the current transaction
1745 * has been committed.
1747 void destroyAfterTransaction(SurfaceControl surface) {
1748 mPendingDestroyingSurfaces.add(surface);
1752 * Destroys any surfaces that have been put into the pending list with
1753 * {@link #destroyAfterTransaction}.
1755 void destroyPendingSurfaces() {
1756 for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
1757 mPendingDestroyingSurfaces.get(i).destroy();
1759 mPendingDestroyingSurfaces.clear();
1762 public void dump(PrintWriter pw, String prefix) {
1763 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1764 pw.print(prefix); pw.print("mHoldScreenWindow="); pw.println(mHoldScreenWindow);
1765 pw.print(prefix); pw.print("mObsuringWindow="); pw.println(mObsuringWindow);