• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.server.wm;
2 
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;
54 
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;
74 
75 import com.android.server.wm.WindowManagerService.H;
76 
77 import java.io.PrintWriter;
78 import java.util.ArrayList;
79 
80 /**
81  * Positions windows and their surfaces.
82  *
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.
85  */
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;
90 
91     private boolean mInLayout = false;
92 
93     /** Only do a maximum of 6 repeated layouts. After that quit */
94     private int mLayoutRepeatCount;
95 
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;
102 
103     boolean mWallpaperMayChange = false;
104     boolean mOrientationChangeComplete = true;
105     boolean mWallpaperActionPending = false;
106 
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();
118 
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;
122 
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;
126 
127     private float mPreferredRefreshRate = 0;
128 
129     private int mPreferredModeId = 0;
130 
131     private boolean mTraversalScheduled;
132     private int mDeferDepth = 0;
133 
134     private boolean mSustainedPerformanceModeEnabled = false;
135     private boolean mSustainedPerformanceModeCurrent = false;
136 
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;
142 
143     private static final class LayerAndToken {
144         public int layer;
145         public AppWindowToken token;
146     }
147     private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
148 
149     private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
150 
WindowSurfacePlacer(WindowManagerService service)151     public WindowSurfacePlacer(WindowManagerService service) {
152         mService = service;
153         mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
154     }
155 
156     /**
157      * See {@link WindowManagerService#deferSurfaceLayout()}
158      */
deferLayout()159     void deferLayout() {
160         mDeferDepth++;
161     }
162 
163     /**
164      * See {@link WindowManagerService#continueSurfaceLayout()}
165      */
continueLayout()166     void continueLayout() {
167         mDeferDepth--;
168         if (mDeferDepth <= 0) {
169             performSurfacePlacement();
170         }
171     }
172 
performSurfacePlacement()173     final void performSurfacePlacement() {
174         if (mDeferDepth > 0) {
175             return;
176         }
177         int loopCount = 6;
178         do {
179             mTraversalScheduled = false;
180             performSurfacePlacementLoop();
181             mService.mH.removeMessages(DO_TRAVERSAL);
182             loopCount--;
183         } while (mTraversalScheduled && loopCount > 0);
184         mWallpaperActionPending = false;
185     }
186 
performSurfacePlacementLoop()187     private void performSurfacePlacementLoop() {
188         if (mInLayout) {
189             if (DEBUG) {
190                 throw new RuntimeException("Recursive call!");
191             }
192             Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
193                     + Debug.getCallers(3));
194             return;
195         }
196 
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.
201             return;
202         }
203 
204         if (!mService.mDisplayReady) {
205             // Not yet initialized, nothing to do.
206             return;
207         }
208 
209         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
210         mInLayout = true;
211 
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);
220             }
221             Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
222             Object tmp = new Object();
223             synchronized (tmp) {
224                 try {
225                     tmp.wait(250);
226                 } catch (InterruptedException e) {
227                 }
228             }
229         }
230 
231         try {
232             performSurfacePlacementInner(recoveringMemory);
233 
234             mInLayout = false;
235 
236             if (mService.needsLayout()) {
237                 if (++mLayoutRepeatCount < 6) {
238                     requestTraversal();
239                 } else {
240                     Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
241                     mLayoutRepeatCount = 0;
242                 }
243             } else {
244                 mLayoutRepeatCount = 0;
245             }
246 
247             if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
248                 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
249                 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
250             }
251         } catch (RuntimeException e) {
252             mInLayout = false;
253             Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
254         }
255 
256         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
257     }
258 
debugLayoutRepeats(final String msg, int pendingLayoutChanges)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));
263         }
264     }
265 
266     // "Something has changed!  Let's make it correct now."
performSurfacePlacementInner(boolean recoveringMemory)267     private void performSurfacePlacementInner(boolean recoveringMemory) {
268         if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
269                 + Debug.getCallers(3));
270 
271         int i;
272         boolean updateInputWindowsNeeded = false;
273 
274         if (mService.mFocusMayChange) {
275             mService.mFocusMayChange = false;
276             updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
277                     UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
278         }
279 
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;
286             }
287         }
288 
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;
295             }
296         }
297 
298         mHoldScreen = null;
299         mHoldScreenWindow = null;
300         mObsuringWindow = null;
301         mScreenBrightness = -1;
302         mButtonBrightness = -1;
303         mUserActivityTimeout = -1;
304         mObscureApplicationContentOnSecondaryDisplays = false;
305         mSustainedPerformanceModeCurrent = false;
306         mService.mTransactionSequence++;
307 
308         final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
309         final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
310         final int defaultDw = defaultInfo.logicalWidth;
311         final int defaultDh = defaultInfo.logicalHeight;
312 
313         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
314                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
315         SurfaceControl.openTransaction();
316         try {
317             applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
318         } catch (RuntimeException e) {
319             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
320         } finally {
321             SurfaceControl.closeTransaction();
322             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
323                     "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
324         }
325 
326         final WindowList defaultWindows = defaultDisplay.getWindowList();
327 
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
330         // to go.
331         if (mService.mAppTransition.isReady()) {
332             defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
333             if (DEBUG_LAYOUT_REPEATS)
334                 debugLayoutRepeats("after handleAppTransitionReadyLocked",
335                         defaultDisplay.pendingLayoutChanges);
336         }
337 
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);
350         }
351 
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);
364         }
365         mWallpaperForceHidingChanged = false;
366 
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);
373         }
374 
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;
381             }
382         }
383 
384         if (mService.needsLayout()) {
385             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
386             if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
387                     defaultDisplay.pendingLayoutChanges);
388         }
389 
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.
394                 continue;
395             }
396             // Discard the saved surface if window size is changed, it can't be reused.
397             if (win.mAppToken != null) {
398                 win.mAppToken.destroySavedSurfaces();
399             }
400             win.reportResized();
401             mService.mResizingWindows.remove(i);
402         }
403 
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);
411             }
412             mService.stopFreezingDisplayLocked();
413         }
414 
415         // Destroy the surface of any windows that are no longer visible.
416         boolean wallpaperDestroyed = false;
417         i = mService.mDestroySurface.size();
418         if (i > 0) {
419             do {
420                 i--;
421                 WindowState win = mService.mDestroySurface.get(i);
422                 win.mDestroying = false;
423                 if (mService.mInputMethodWindow == win) {
424                     mService.mInputMethodWindow = null;
425                 }
426                 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
427                     wallpaperDestroyed = true;
428                 }
429                 win.destroyOrSaveSurface();
430             } while (i > 0);
431             mService.mDestroySurface.clear();
432         }
433 
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);
444                     }
445                 }
446             }
447         }
448 
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();
466                 }
467             }
468         }
469 
470         if (wallpaperDestroyed) {
471             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
472             defaultDisplay.layoutNeeded = true;
473         }
474 
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;
479             }
480         }
481 
482         // Finally update all input windows now that the window changes have stabilized.
483         mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
484 
485         mService.setHoldScreenLocked(mHoldScreen);
486         if (!mService.mDisplayFrozen) {
487             if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
488                 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
489             } else {
490                 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
491                         toBrightnessOverride(mScreenBrightness));
492             }
493             if (mButtonBrightness < 0
494                     || mButtonBrightness > 1.0f) {
495                 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
496             } else {
497                 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
498                         toBrightnessOverride(mButtonBrightness));
499             }
500             mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
501                     mUserActivityTimeout);
502         }
503 
504         if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
505             mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
506             mService.mPowerManagerInternal.powerHint(
507                     mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
508                     (mSustainedPerformanceModeEnabled ? 1 : 0));
509         }
510 
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!");
517                 }
518                 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
519                         "android.server.wm:TURN_ON");
520             }
521             mService.mTurnOnScreen = false;
522         }
523 
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);
528             } else {
529                 mUpdateRotation = false;
530             }
531         }
532 
533         if (mService.mWaitingForDrawnCallback != null ||
534                 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
535                         !mUpdateRotation)) {
536             mService.checkDrawnWindowsLocked();
537         }
538 
539         final int N = mService.mPendingRemove.size();
540         if (N > 0) {
541             if (mService.mPendingRemoveTmp.length < N) {
542                 mService.mPendingRemoveTmp = new WindowState[N+10];
543             }
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);
553                 }
554             }
555 
556             for (DisplayContent displayContent : displayList) {
557                 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
558                 displayContent.layoutNeeded = true;
559             }
560         }
561 
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();
565         }
566 
567         if (updateInputWindowsNeeded) {
568             mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
569         }
570         mService.setFocusTaskRegionLocked();
571 
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();
575 
576         mService.scheduleAnimationLocked();
577         mService.mWindowPlacerLocked.destroyPendingSurfaces();
578 
579         if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
580                 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
581     }
582 
applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays, int defaultDw, int defaultDh)583     private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
584             int defaultDw, int defaultDh) {
585         if (mService.mWatermark != null) {
586             mService.mWatermark.positionSurface(defaultDw, defaultDh);
587         }
588         if (mService.mStrictModeFlash != null) {
589             mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
590         }
591         if (mService.mCircularDisplayMask != null) {
592             mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
593                     mService.mRotation);
594         }
595         if (mService.mEmulatorDisplayOverlay != null) {
596             mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
597                     mService.mRotation);
598         }
599 
600         boolean focusDisplayed = false;
601 
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);
613 
614             // Reset for each display.
615             mDisplayHasContent = false;
616             mPreferredRefreshRate = 0;
617             mPreferredModeId = 0;
618 
619             int repeats = 0;
620             do {
621                 repeats++;
622                 if (repeats > 6) {
623                     Slog.w(TAG, "Animation repeat aborted after too many iterations");
624                     displayContent.layoutNeeded = false;
625                     break;
626                 }
627 
628                 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
629                         "On entry to LockedInner", displayContent.pendingLayoutChanges);
630 
631                 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
632                         mWallpaperControllerLocked.adjustWallpaperWindows()) {
633                     mService.mLayersController.assignLayersLocked(windows);
634                     displayContent.layoutNeeded = true;
635                 }
636 
637                 if (isDefaultDisplay
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);
643                     }
644                 }
645 
646                 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
647                     displayContent.layoutNeeded = true;
648                 }
649 
650                 // FIRST LOOP: Perform a layout, if needed.
651                 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
652                     performLayoutLockedInner(displayContent, repeats == 1,
653                             false /* updateInputWindows */);
654                 } else {
655                     Slog.w(TAG, "Layout repeat skipped after too many iterations");
656                 }
657 
658                 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
659                 // it is animating.
660                 displayContent.pendingLayoutChanges = 0;
661 
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);
666                         if (w.mHasSurface) {
667                             mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
668                                     w.mAttachedWindow);
669                         }
670                     }
671                     displayContent.pendingLayoutChanges |=
672                             mService.mPolicy.finishPostLayoutPolicyLw();
673                     if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
674                             displayContent.pendingLayoutChanges);
675                 }
676             } while (displayContent.pendingLayoutChanges != 0);
677 
678             mObscured = false;
679             mSyswin = false;
680             displayContent.resetDimming();
681 
682             // Only used if default window
683             final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
684 
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;
689 
690                 // Update effect.
691                 w.mObscured = mObscured;
692                 if (!mObscured) {
693                     handleNotObscuredLocked(w, displayInfo);
694                 }
695 
696                 w.applyDimLayerIfNeeded();
697 
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();
704                 }
705 
706                 final WindowStateAnimator winAnimator = w.mWinAnimator;
707 
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
711                 // for animation.
712                 if (w.hasMoved()) {
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);
725                     }
726 
727                     //TODO (multidisplay): Accessibility supported only for the default display.
728                     if (mService.mAccessibilityController != null
729                             && displayId == Display.DEFAULT_DISPLAY) {
730                         mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
731                     }
732 
733                     try {
734                         w.mClient.moved(left, top);
735                     } catch (RemoteException e) {
736                     }
737                     w.mMovedByResize = false;
738                 }
739 
740                 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
741                 w.mContentChanged = false;
742 
743                 // Moved from updateWindowsAndWallpaperLocked().
744                 if (w.mHasSurface) {
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();
748 
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
756                             // make this happen.
757                             displayContent.pendingLayoutChanges |=
758                                     FINISH_LAYOUT_REDO_LAYOUT;
759                             if (DEBUG_LAYOUT_REPEATS) {
760                                 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
761                                         displayContent.pendingLayoutChanges);
762                             }
763                         }
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);
772                             }
773                         }
774                     }
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.
780                         //
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();
785                     }
786                     winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
787                 }
788 
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);
794                 }
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;
803                     }
804                     if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
805                         if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
806                             Slog.v(TAG, "Eval win " + w + ": isDrawn="
807                                     + w.isDrawnLw()
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);
817                             }
818                         }
819                         if (w != atoken.startingWindow) {
820                             if (w.isInteresting()) {
821                                 atoken.numInterestingWindows++;
822                                 if (w.isDrawnLw()) {
823                                     atoken.numDrawnWindows++;
824                                     if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
825                                         Slog.v(TAG, "tokenMayBeDrawn: " + atoken
826                                                 + " w=" + w + " numInteresting="
827                                                 + atoken.numInterestingWindows
828                                                 + " freezingScreen="
829                                                 + atoken.mAppAnimator.freezingScreen
830                                                 + " mAppFreezing=" + w.mAppFreezing);
831                                     updateAllDrawn = true;
832                                 }
833                             }
834                         } else if (w.isDrawnLw()) {
835                             mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
836                             atoken.startingDisplayed = true;
837                         }
838                     }
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
849                                             + " freezingScreen="
850                                             + atoken.mAppAnimator.freezingScreen
851                                             + " mAppFreezing=" + w.mAppFreezing);
852                                 updateAllDrawn = true;
853                             }
854                         }
855                     }
856                 }
857 
858                 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
859                         && w.isDisplayedLw()) {
860                     focusDisplayed = true;
861                 }
862 
863                 mService.updateResizingWindows(w);
864             }
865 
866             mService.mDisplayManagerInternal.setDisplayProperties(displayId,
867                     mDisplayHasContent,
868                     mPreferredRefreshRate,
869                     mPreferredModeId,
870                     true /* inTraversal, must call performTraversalInTrans... below */);
871 
872             mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
873 
874             if (updateAllDrawn) {
875                 updateAllDrawnLocked(displayContent);
876             }
877         }
878 
879         if (focusDisplayed) {
880             mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
881         }
882 
883         // Give the display manager a chance to adjust properties
884         // like display rotation if it needs to.
885         mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
886     }
887 
isInLayout()888     boolean isInLayout() {
889         return mInLayout;
890     }
891 
performLayoutLockedInner(final DisplayContent displayContent, boolean initial, boolean updateInputWindows)892     final void performLayoutLockedInner(final DisplayContent displayContent,
893             boolean initial, boolean updateInputWindows) {
894         if (!displayContent.layoutNeeded) {
895             return;
896         }
897         displayContent.layoutNeeded = false;
898         WindowList windows = displayContent.getWindowList();
899         boolean isDefaultDisplay = displayContent.isDefaultDisplay;
900 
901         DisplayInfo displayInfo = displayContent.getDisplayInfo();
902         final int dw = displayInfo.logicalWidth;
903         final int dh = displayInfo.logicalHeight;
904 
905         if (mService.mInputConsumer != null) {
906             mService.mInputConsumer.layout(dw, dh);
907         }
908 
909         if (mService.mWallpaperInputConsumer != null) {
910             mService.mWallpaperInputConsumer.layout(dw, dh);
911         }
912 
913         final int N = windows.size();
914         int i;
915 
916         if (DEBUG_LAYOUT) {
917             Slog.v(TAG, "-------------------------------------");
918             Slog.v(TAG, "performLayout: needed="
919                     + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
920         }
921 
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);
928         }
929 
930         mService.mPolicy.getContentRectLw(mTmpContentRect);
931         displayContent.resize(mTmpContentRect);
932 
933         int seq = mService.mLayoutSeq+1;
934         if (seq < 0) seq = 0;
935         mService.mLayoutSeq = seq;
936 
937         boolean behindDream = false;
938 
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);
944 
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();
950 
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);
969             }
970 
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) {
983                     if (initial) {
984                         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
985                         win.mContentChanged = false;
986                     }
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.
991                         behindDream = true;
992                     }
993                     win.mLayoutNeeded = false;
994                     win.prelayout();
995                     mService.mPolicy.layoutWindowLw(win, null);
996                     win.mLayoutSeq = seq;
997 
998                     // Window frames may have changed. Update dim layer with the new bounds.
999                     final Task task = win.getTask();
1000                     if (task != null) {
1001                         displayContent.mDimLayerController.updateDimLayer(task);
1002                     }
1003 
1004                     if (DEBUG_LAYOUT) Slog.v(TAG,
1005                             "  LAYOUT: mFrame="
1006                             + win.mFrame + " mContainingFrame="
1007                             + win.mContainingFrame + " mDisplayFrame="
1008                             + win.mDisplayFrame);
1009                 } else {
1010                     if (topAttached < 0) topAttached = i;
1011                 }
1012             }
1013         }
1014 
1015         boolean attachedBehindDream = false;
1016 
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);
1023 
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)) {
1034                     continue;
1035                 }
1036                 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
1037                         || !win.mHaveFrame || win.mLayoutNeeded) {
1038                     if (initial) {
1039                         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
1040                         win.mContentChanged = false;
1041                     }
1042                     win.mLayoutNeeded = false;
1043                     win.prelayout();
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);
1049                 }
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;
1055             }
1056         }
1057 
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*/);
1062         }
1063 
1064         mService.mPolicy.finishLayoutLw();
1065         mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
1066     }
1067 
1068     /**
1069      * @param windows List of windows on default display.
1070      * @return bitmap indicating if another pass through layout must be made.
1071      */
handleAppTransitionReadyLocked(WindowList windows)1072     private int handleAppTransitionReadyLocked(WindowList windows) {
1073         int appsCount = mService.mOpeningApps.size();
1074         if (!transitionGoodToGo(appsCount)) {
1075             return 0;
1076         }
1077         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
1078 
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;
1083         }
1084         mService.mSkipAppTransitionAnimation = false;
1085         mService.mNoAnimationNotifyOnTransitionFinished.clear();
1086 
1087         mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
1088 
1089         mService.rebuildAppWindowListLocked();
1090 
1091         mWallpaperMayChange = false;
1092 
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;
1099 
1100         int i;
1101         for (i = 0; i < appsCount; i++) {
1102             final AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1103             // Clearing the mAnimatingExit flag before entering animation. It's set to
1104             // true if app window is removed, or window relayout to invisible.
1105             // This also affects window visibility. We need to clear it *before*
1106             // maybeUpdateTransitToWallpaper() as the transition selection depends on
1107             // wallpaper target visibility.
1108             wtoken.clearAnimatingFlags();
1109 
1110         }
1111         // Adjust wallpaper before we pull the lower/upper target, since pending changes
1112         // (like the clearAnimatingFlags() above) might affect wallpaper target result.
1113         final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1114         if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
1115                 mWallpaperControllerLocked.adjustWallpaperWindows()) {
1116             mService.mLayersController.assignLayersLocked(windows);
1117             displayContent.layoutNeeded = true;
1118         }
1119 
1120         final WindowState lowerWallpaperTarget =
1121                 mWallpaperControllerLocked.getLowerWallpaperTarget();
1122         final WindowState upperWallpaperTarget =
1123                 mWallpaperControllerLocked.getUpperWallpaperTarget();
1124 
1125         boolean openingAppHasWallpaper = false;
1126         boolean closingAppHasWallpaper = false;
1127         final AppWindowToken lowerWallpaperAppToken;
1128         final AppWindowToken upperWallpaperAppToken;
1129         if (lowerWallpaperTarget == null) {
1130             lowerWallpaperAppToken = upperWallpaperAppToken = null;
1131         } else {
1132             lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1133             upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1134         }
1135 
1136         // Do a first pass through the tokens for two
1137         // things:
1138         // (1) Determine if both the closing and opening
1139         // app token sets are wallpaper targets, in which
1140         // case special animations are needed
1141         // (since the wallpaper needs to stay static
1142         // behind them).
1143         // (2) Find the layout params of the top-most
1144         // application window in the tokens, which is
1145         // what will control the animation theme.
1146         final int closingAppsCount = mService.mClosingApps.size();
1147         appsCount = closingAppsCount + mService.mOpeningApps.size();
1148         for (i = 0; i < appsCount; i++) {
1149             final AppWindowToken wtoken;
1150             if (i < closingAppsCount) {
1151                 wtoken = mService.mClosingApps.valueAt(i);
1152                 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1153                     closingAppHasWallpaper = true;
1154                 }
1155             } else {
1156                 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1157                 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1158                     openingAppHasWallpaper = true;
1159                 }
1160             }
1161 
1162             voiceInteraction |= wtoken.voiceInteraction;
1163 
1164             if (wtoken.appFullscreen) {
1165                 WindowState ws = wtoken.findMainWindow();
1166                 if (ws != null) {
1167                     animLp = ws.mAttrs;
1168                     bestAnimLayer = ws.mLayer;
1169                     fullscreenAnim = true;
1170                 }
1171             } else if (!fullscreenAnim) {
1172                 WindowState ws = wtoken.findMainWindow();
1173                 if (ws != null) {
1174                     if (ws.mLayer > bestAnimLayer) {
1175                         animLp = ws.mAttrs;
1176                         bestAnimLayer = ws.mLayer;
1177                     }
1178                 }
1179             }
1180         }
1181 
1182         transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1183                 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1184 
1185         // If all closing windows are obscured, then there is
1186         // no need to do an animation.  This is the case, for
1187         // example, when this transition is being done behind
1188         // the lock screen.
1189         if (!mService.mPolicy.allowAppAnimationsLw()) {
1190             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1191                     "Animations disallowed by keyguard or dream.");
1192             animLp = null;
1193         }
1194 
1195         processApplicationsAnimatingInPlace(transit);
1196 
1197         mTmpLayerAndToken.token = null;
1198         handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1199         final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1200         final int topClosingLayer = mTmpLayerAndToken.layer;
1201 
1202         final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1203                 animLp, voiceInteraction, topClosingLayer);
1204 
1205         mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
1206 
1207         final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
1208                 topOpeningApp.mAppAnimator;
1209         final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1210                 topClosingApp.mAppAnimator;
1211 
1212         mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1213                 mService.mOpeningApps, mService.mClosingApps);
1214         mService.mAppTransition.postAnimationCallback();
1215         mService.mAppTransition.clear();
1216 
1217         mService.mOpeningApps.clear();
1218         mService.mClosingApps.clear();
1219 
1220         // This has changed the visibility of windows, so perform
1221         // a new layout to get them all up-to-date.
1222         displayContent.layoutNeeded = true;
1223 
1224         // TODO(multidisplay): IMEs are only supported on the default display.
1225         if (windows == mService.getDefaultWindowListLocked()
1226                 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
1227             mService.mLayersController.assignLayersLocked(windows);
1228         }
1229         mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1230                 true /*updateInputWindows*/);
1231         mService.mFocusMayChange = false;
1232         mService.notifyActivityDrawnForKeyguard();
1233 
1234         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1235 
1236         return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1237     }
1238 
handleOpeningApps(int transit, LayoutParams animLp, boolean voiceInteraction, int topClosingLayer)1239     private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1240             boolean voiceInteraction, int topClosingLayer) {
1241         AppWindowToken topOpeningApp = null;
1242         final int appsCount = mService.mOpeningApps.size();
1243         for (int i = 0; i < appsCount; i++) {
1244             AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1245             final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1246             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
1247 
1248             if (!appAnimator.usingTransferredAnimation) {
1249                 appAnimator.clearThumbnail();
1250                 appAnimator.setNullAnimation();
1251             }
1252             wtoken.inPendingTransaction = false;
1253 
1254             if (!mService.setTokenVisibilityLocked(
1255                     wtoken, animLp, true, transit, false, voiceInteraction)){
1256                 // This token isn't going to be animating. Add it to the list of tokens to
1257                 // be notified of app transition complete since the notification will not be
1258                 // sent be the app window animator.
1259                 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1260             }
1261             wtoken.updateReportedVisibilityLocked();
1262             wtoken.waitingToShow = false;
1263 
1264             appAnimator.mAllAppWinAnimators.clear();
1265             final int windowsCount = wtoken.allAppWindows.size();
1266             for (int j = 0; j < windowsCount; j++) {
1267                 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1268             }
1269             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1270                     ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1271             SurfaceControl.openTransaction();
1272             try {
1273                 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
1274             } finally {
1275                 SurfaceControl.closeTransaction();
1276                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1277                         "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1278             }
1279             mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1280 
1281             int topOpeningLayer = 0;
1282             if (animLp != null) {
1283                 int layer = -1;
1284                 for (int j = 0; j < wtoken.allAppWindows.size(); j++) {
1285                     final WindowState win = wtoken.allAppWindows.get(j);
1286                     if (win.mWinAnimator.mAnimLayer > layer) {
1287                         layer = win.mWinAnimator.mAnimLayer;
1288                     }
1289                 }
1290                 if (topOpeningApp == null || layer > topOpeningLayer) {
1291                     topOpeningApp = wtoken;
1292                     topOpeningLayer = layer;
1293                 }
1294             }
1295             if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1296                 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1297             }
1298         }
1299         return topOpeningApp;
1300     }
1301 
handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction, LayerAndToken layerAndToken)1302     private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1303             LayerAndToken layerAndToken) {
1304         final int appsCount;
1305         appsCount = mService.mClosingApps.size();
1306         for (int i = 0; i < appsCount; i++) {
1307             AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1308 
1309             // If we still have some windows animating with saved surfaces that's
1310             // either invisible or already removed, mark them exiting so that they
1311             // are disposed of after the exit animation. These are not supposed to
1312             // be shown, or are delayed removal until app is actually drawn (in which
1313             // case the window will be removed after the animation).
1314             wtoken.markSavedSurfaceExiting();
1315 
1316             final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1317             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
1318             appAnimator.clearThumbnail();
1319             appAnimator.setNullAnimation();
1320             wtoken.inPendingTransaction = false;
1321             mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1322                     voiceInteraction);
1323             wtoken.updateReportedVisibilityLocked();
1324             // Force the allDrawn flag, because we want to start
1325             // this guy's animations regardless of whether it's
1326             // gotten drawn.
1327             wtoken.allDrawn = true;
1328             wtoken.deferClearAllDrawn = false;
1329             // Ensure that apps that are mid-starting are also scheduled to have their
1330             // starting windows removed after the animation is complete
1331             if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
1332                 mService.scheduleRemoveStartingWindowLocked(wtoken);
1333             }
1334             mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1335 
1336             if (animLp != null) {
1337                 int layer = -1;
1338                 for (int j = 0; j < wtoken.windows.size(); j++) {
1339                     WindowState win = wtoken.windows.get(j);
1340                     if (win.mWinAnimator.mAnimLayer > layer) {
1341                         layer = win.mWinAnimator.mAnimLayer;
1342                     }
1343                 }
1344                 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1345                     layerAndToken.token = wtoken;
1346                     layerAndToken.layer = layer;
1347                 }
1348             }
1349             if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1350                 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1351             }
1352         }
1353     }
1354 
transitionGoodToGo(int appsCount)1355     private boolean transitionGoodToGo(int appsCount) {
1356         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1357                 "Checking " + appsCount + " opening apps (frozen="
1358                         + mService.mDisplayFrozen + " timeout="
1359                         + mService.mAppTransition.isTimeout() + ")...");
1360         int reason = APP_TRANSITION_TIMEOUT;
1361         if (!mService.mAppTransition.isTimeout()) {
1362             for (int i = 0; i < appsCount; i++) {
1363                 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1364                 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1365                         "Check opening app=" + wtoken + ": allDrawn="
1366                         + wtoken.allDrawn + " startingDisplayed="
1367                         + wtoken.startingDisplayed + " startingMoved="
1368                         + wtoken.startingMoved + " isRelaunching()="
1369                         + wtoken.isRelaunching());
1370 
1371                 if (wtoken.isRelaunching()) {
1372                     return false;
1373                 }
1374 
1375                 final boolean drawnBeforeRestoring = wtoken.allDrawn;
1376                 wtoken.restoreSavedSurfaces();
1377 
1378                 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1379                     return false;
1380                 }
1381                 if (wtoken.allDrawn) {
1382                     reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1383                             : APP_TRANSITION_SAVED_SURFACE;
1384                 } else {
1385                     reason = APP_TRANSITION_STARTING_WINDOW;
1386                 }
1387             }
1388 
1389             // We also need to wait for the specs to be fetched, if needed.
1390             if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
1391                 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
1392                 return false;
1393             }
1394 
1395             // If the wallpaper is visible, we need to check it's ready too.
1396             boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
1397                     mWallpaperControllerLocked.wallpaperTransitionReady();
1398             if (wallpaperReady) {
1399                 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1400                 return true;
1401             }
1402             return false;
1403         }
1404         mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1405         return true;
1406     }
1407 
maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper, boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget, WindowState upperWallpaperTarget)1408     private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1409             boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1410             WindowState upperWallpaperTarget) {
1411         // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1412         final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1413         final WindowState oldWallpaper =
1414                 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1415                         ? null : wallpaperTarget;
1416         final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1417         final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
1418         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1419                 "New wallpaper target=" + wallpaperTarget
1420                         + ", oldWallpaper=" + oldWallpaper
1421                         + ", lower target=" + lowerWallpaperTarget
1422                         + ", upper target=" + upperWallpaperTarget
1423                         + ", openingApps=" + openingApps
1424                         + ", closingApps=" + closingApps);
1425         mService.mAnimateWallpaperWithTarget = false;
1426         if (closingAppHasWallpaper && openingAppHasWallpaper) {
1427             if (DEBUG_APP_TRANSITIONS)
1428                 Slog.v(TAG, "Wallpaper animation!");
1429             switch (transit) {
1430                 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1431                 case AppTransition.TRANSIT_TASK_OPEN:
1432                 case AppTransition.TRANSIT_TASK_TO_FRONT:
1433                     transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1434                     break;
1435                 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1436                 case AppTransition.TRANSIT_TASK_CLOSE:
1437                 case AppTransition.TRANSIT_TASK_TO_BACK:
1438                     transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1439                     break;
1440             }
1441             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1442                     "New transit: " + AppTransition.appTransitionToString(transit));
1443         } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1444                 && !openingApps.contains(oldWallpaper.mAppToken)
1445                 && closingApps.contains(oldWallpaper.mAppToken)) {
1446             // We are transitioning from an activity with a wallpaper to one without.
1447             transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
1448             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1449                     "New transit away from wallpaper: "
1450                     + AppTransition.appTransitionToString(transit));
1451         } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1452                 openingApps.contains(wallpaperTarget.mAppToken)) {
1453             // We are transitioning from an activity without
1454             // a wallpaper to now showing the wallpaper
1455             transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
1456             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1457                     "New transit into wallpaper: "
1458                     + AppTransition.appTransitionToString(transit));
1459         } else {
1460             mService.mAnimateWallpaperWithTarget = true;
1461         }
1462         return transit;
1463     }
1464 
1465     /**
1466      * @param w WindowState this method is applied to.
1467      * @param dispInfo info of the display that the window's obscuring state is checked against.
1468      */
handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo)1469     private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
1470         final LayoutParams attrs = w.mAttrs;
1471         final int attrFlags = attrs.flags;
1472         final boolean canBeSeen = w.isDisplayedLw();
1473         final int privateflags = attrs.privateFlags;
1474 
1475         if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
1476             // This window completely covers everything behind it,
1477             // so we want to leave all of them as undimmed (for
1478             // performance reasons).
1479             if (!mObscured) {
1480                 mObsuringWindow = w;
1481             }
1482 
1483             mObscured = true;
1484         }
1485 
1486         if (w.mHasSurface && canBeSeen) {
1487             if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1488                 mHoldScreen = w.mSession;
1489                 mHoldScreenWindow = w;
1490             } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
1491                 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
1492                         + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
1493                         + Debug.getCallers(10));
1494             }
1495             if (!mSyswin && w.mAttrs.screenBrightness >= 0
1496                     && mScreenBrightness < 0) {
1497                 mScreenBrightness = w.mAttrs.screenBrightness;
1498             }
1499             if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1500                     && mButtonBrightness < 0) {
1501                 mButtonBrightness = w.mAttrs.buttonBrightness;
1502             }
1503             if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1504                     && mUserActivityTimeout < 0) {
1505                 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1506             }
1507 
1508             final int type = attrs.type;
1509             if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
1510                     || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1511                 mSyswin = true;
1512             }
1513 
1514             // This function assumes that the contents of the default display are
1515             // processed first before secondary displays.
1516             final DisplayContent displayContent = w.getDisplayContent();
1517             if (displayContent != null && displayContent.isDefaultDisplay) {
1518                 // While a dream or keyguard is showing, obscure ordinary application
1519                 // content on secondary displays (by forcibly enabling mirroring unless
1520                 // there is other content we want to show) but still allow opaque
1521                 // keyguard dialogs to be shown.
1522                 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1523                     mObscureApplicationContentOnSecondaryDisplays = true;
1524                 }
1525                 mDisplayHasContent = true;
1526             } else if (displayContent != null &&
1527                     (!mObscureApplicationContentOnSecondaryDisplays
1528                             || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1529                 // Allow full screen keyguard presentation dialogs to be seen.
1530                 mDisplayHasContent = true;
1531             }
1532             if (mPreferredRefreshRate == 0
1533                     && w.mAttrs.preferredRefreshRate != 0) {
1534                 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1535             }
1536             if (mPreferredModeId == 0
1537                     && w.mAttrs.preferredDisplayModeId != 0) {
1538                 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1539             }
1540             if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1541                 mSustainedPerformanceModeCurrent = true;
1542             }
1543         }
1544     }
1545 
updateAllDrawnLocked(DisplayContent displayContent)1546     private void updateAllDrawnLocked(DisplayContent displayContent) {
1547         // See if any windows have been drawn, so they (and others
1548         // associated with them) can now be shown.
1549         ArrayList<TaskStack> stacks = displayContent.getStacks();
1550         for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1551             final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1552             for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1553                 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1554                 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1555                     final AppWindowToken wtoken = tokens.get(tokenNdx);
1556                     if (!wtoken.allDrawn) {
1557                         int numInteresting = wtoken.numInterestingWindows;
1558                         if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1559                             if (DEBUG_VISIBILITY)
1560                                 Slog.v(TAG, "allDrawn: " + wtoken
1561                                     + " interesting=" + numInteresting
1562                                     + " drawn=" + wtoken.numDrawnWindows);
1563                             wtoken.allDrawn = true;
1564                             // Force an additional layout pass where WindowStateAnimator#
1565                             // commitFinishDrawingLocked() will call performShowLocked().
1566                             displayContent.layoutNeeded = true;
1567                             mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1568                                     wtoken.token).sendToTarget();
1569                         }
1570                     }
1571                     if (!wtoken.allDrawnExcludingSaved) {
1572                         int numInteresting = wtoken.numInterestingWindowsExcludingSaved;
1573                         if (numInteresting > 0
1574                                 && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) {
1575                             if (DEBUG_VISIBILITY)
1576                                 Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken
1577                                     + " interesting=" + numInteresting
1578                                     + " drawn=" + wtoken.numDrawnWindowsExclusingSaved);
1579                             wtoken.allDrawnExcludingSaved = true;
1580                             displayContent.layoutNeeded = true;
1581                             if (wtoken.isAnimatingInvisibleWithSavedSurface()
1582                                     && !mService.mFinishedEarlyAnim.contains(wtoken)) {
1583                                 mService.mFinishedEarlyAnim.add(wtoken);
1584                             }
1585                         }
1586                     }
1587                 }
1588             }
1589         }
1590     }
1591 
toBrightnessOverride(float value)1592     private static int toBrightnessOverride(float value) {
1593         return (int)(value * PowerManager.BRIGHTNESS_ON);
1594     }
1595 
processApplicationsAnimatingInPlace(int transit)1596     private void processApplicationsAnimatingInPlace(int transit) {
1597         if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1598             // Find the focused window
1599             final WindowState win = mService.findFocusedWindowLocked(
1600                     mService.getDefaultDisplayContentLocked());
1601             if (win != null) {
1602                 final AppWindowToken wtoken = win.mAppToken;
1603                 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1604                 if (DEBUG_APP_TRANSITIONS)
1605                     Slog.v(TAG, "Now animating app in place " + wtoken);
1606                 appAnimator.clearThumbnail();
1607                 appAnimator.setNullAnimation();
1608                 mService.updateTokenInPlaceLocked(wtoken, transit);
1609                 wtoken.updateReportedVisibilityLocked();
1610 
1611                 appAnimator.mAllAppWinAnimators.clear();
1612                 final int N = wtoken.allAppWindows.size();
1613                 for (int j = 0; j < N; j++) {
1614                     appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1615                 }
1616                 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1617                 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
1618             }
1619         }
1620     }
1621 
createThumbnailAppAnimator(int transit, AppWindowToken appToken, int openingLayer, int closingLayer)1622     private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1623             int openingLayer, int closingLayer) {
1624         AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1625         if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1626             return;
1627         }
1628         final int taskId = appToken.mTask.mTaskId;
1629         Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1630         if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
1631             if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
1632             return;
1633         }
1634         // This thumbnail animation is very special, we need to have
1635         // an extra surface with the thumbnail included with the animation.
1636         Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1637         try {
1638             // TODO(multi-display): support other displays
1639             final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1640             final Display display = displayContent.getDisplay();
1641             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1642 
1643             // Create a new surface for the thumbnail
1644             SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1645                     "thumbnail anim", dirty.width(), dirty.height(),
1646                     PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1647             surfaceControl.setLayerStack(display.getLayerStack());
1648             if (SHOW_TRANSACTIONS) {
1649                 Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
1650             }
1651 
1652             // Draw the thumbnail onto the surface
1653             Surface drawSurface = new Surface();
1654             drawSurface.copyFrom(surfaceControl);
1655             Canvas c = drawSurface.lockCanvas(dirty);
1656             c.drawBitmap(thumbnailHeader, 0, 0, null);
1657             drawSurface.unlockCanvasAndPost(c);
1658             drawSurface.release();
1659 
1660             // Get the thumbnail animation
1661             Animation anim;
1662             if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1663                 // If this is a multi-window scenario, we use the windows frame as
1664                 // destination of the thumbnail header animation. If this is a full screen
1665                 // window scenario, we use the whole display as the target.
1666                 WindowState win = appToken.findMainWindow();
1667                 Rect appRect = win != null ? win.getContentFrameLw() :
1668                         new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1669                 Rect insets = win != null ? win.mContentInsets : null;
1670                 // For the new aspect-scaled transition, we want it to always show
1671                 // above the animating opening/closing window, and we want to
1672                 // synchronize its thumbnail surface with the surface for the
1673                 // open/close animation (only on the way down)
1674                 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
1675                         insets, thumbnailHeader, taskId, mService.mCurConfiguration.uiMode,
1676                         mService.mCurConfiguration.orientation);
1677                 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1678                 openingAppAnimator.deferThumbnailDestruction =
1679                         !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1680             } else {
1681                 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1682                         displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1683             }
1684             anim.restrictDuration(MAX_ANIMATION_DURATION);
1685             anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1686 
1687             openingAppAnimator.thumbnail = surfaceControl;
1688             openingAppAnimator.thumbnailLayer = openingLayer;
1689             openingAppAnimator.thumbnailAnimation = anim;
1690             mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
1691         } catch (Surface.OutOfResourcesException e) {
1692             Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
1693                     + dirty.width() + " h=" + dirty.height(), e);
1694             openingAppAnimator.clearThumbnail();
1695         }
1696     }
1697 
copyAnimToLayoutParamsLocked()1698     boolean copyAnimToLayoutParamsLocked() {
1699         boolean doRequest = false;
1700 
1701         final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1702         if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1703             mUpdateRotation = true;
1704             doRequest = true;
1705         }
1706         if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1707             mWallpaperMayChange = true;
1708             doRequest = true;
1709         }
1710         if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1711             mWallpaperForceHidingChanged = true;
1712             doRequest = true;
1713         }
1714         if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1715             mOrientationChangeComplete = false;
1716         } else {
1717             mOrientationChangeComplete = true;
1718             mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1719             if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1720                 doRequest = true;
1721             }
1722         }
1723         if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1724             mService.mTurnOnScreen = true;
1725         }
1726         if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1727             mWallpaperActionPending = true;
1728         }
1729 
1730         return doRequest;
1731     }
1732 
requestTraversal()1733     void requestTraversal() {
1734         if (!mTraversalScheduled) {
1735             mTraversalScheduled = true;
1736             mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1737         }
1738     }
1739 
1740     /**
1741      * Puts the {@param surface} into a pending list to be destroyed after the current transaction
1742      * has been committed.
1743      */
destroyAfterTransaction(SurfaceControl surface)1744     void destroyAfterTransaction(SurfaceControl surface) {
1745         mPendingDestroyingSurfaces.add(surface);
1746     }
1747 
1748     /**
1749      * Destroys any surfaces that have been put into the pending list with
1750      * {@link #destroyAfterTransaction}.
1751      */
destroyPendingSurfaces()1752     void destroyPendingSurfaces() {
1753         for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
1754             mPendingDestroyingSurfaces.get(i).destroy();
1755         }
1756         mPendingDestroyingSurfaces.clear();
1757     }
1758 
dump(PrintWriter pw, String prefix)1759     public void dump(PrintWriter pw, String prefix) {
1760         pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1761         pw.print(prefix); pw.print("mHoldScreenWindow="); pw.println(mHoldScreenWindow);
1762         pw.print(prefix); pw.print("mObsuringWindow="); pw.println(mObsuringWindow);
1763     }
1764 }
1765