• 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     // During an orientation change, we track whether all windows have rendered
105     // at the new orientation, and this will be false from changing orientation until that occurs.
106     // For seamless rotation cases this always stays true, as the windows complete their orientation
107     // changes 1 by 1 without disturbing global state.
108     boolean mOrientationChangeComplete = true;
109     boolean mWallpaperActionPending = false;
110 
111     private boolean mWallpaperForceHidingChanged = false;
112     private Object mLastWindowFreezeSource = null;
113     private Session mHoldScreen = null;
114     private boolean mObscured = false;
115     private boolean mSyswin = false;
116     private float mScreenBrightness = -1;
117     private float mButtonBrightness = -1;
118     private long mUserActivityTimeout = -1;
119     private boolean mUpdateRotation = false;
120     private final Rect mTmpStartRect = new Rect();
121     private final Rect mTmpContentRect = new Rect();
122 
123     // Set to true when the display contains content to show the user.
124     // When false, the display manager may choose to mirror or blank the display.
125     private boolean mDisplayHasContent = false;
126 
127     // Only set while traversing the default display based on its content.
128     // Affects the behavior of mirroring on secondary displays.
129     private boolean mObscureApplicationContentOnSecondaryDisplays = false;
130 
131     private float mPreferredRefreshRate = 0;
132 
133     private int mPreferredModeId = 0;
134 
135     private boolean mTraversalScheduled;
136     private int mDeferDepth = 0;
137 
138     private boolean mSustainedPerformanceModeEnabled = false;
139     private boolean mSustainedPerformanceModeCurrent = false;
140 
141     // Following variables are for debugging screen wakelock only.
142     // Last window that requires screen wakelock
143     WindowState mHoldScreenWindow = null;
144     // Last window that obscures all windows below
145     WindowState mObsuringWindow = null;
146 
147     private static final class LayerAndToken {
148         public int layer;
149         public AppWindowToken token;
150     }
151     private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
152 
153     private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
154 
WindowSurfacePlacer(WindowManagerService service)155     public WindowSurfacePlacer(WindowManagerService service) {
156         mService = service;
157         mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
158     }
159 
160     /**
161      * See {@link WindowManagerService#deferSurfaceLayout()}
162      */
deferLayout()163     void deferLayout() {
164         mDeferDepth++;
165     }
166 
167     /**
168      * See {@link WindowManagerService#continueSurfaceLayout()}
169      */
continueLayout()170     void continueLayout() {
171         mDeferDepth--;
172         if (mDeferDepth <= 0) {
173             performSurfacePlacement();
174         }
175     }
176 
performSurfacePlacement()177     final void performSurfacePlacement() {
178         if (mDeferDepth > 0) {
179             return;
180         }
181         int loopCount = 6;
182         do {
183             mTraversalScheduled = false;
184             performSurfacePlacementLoop();
185             mService.mH.removeMessages(DO_TRAVERSAL);
186             loopCount--;
187         } while (mTraversalScheduled && loopCount > 0);
188         mWallpaperActionPending = false;
189     }
190 
performSurfacePlacementLoop()191     private void performSurfacePlacementLoop() {
192         if (mInLayout) {
193             if (DEBUG) {
194                 throw new RuntimeException("Recursive call!");
195             }
196             Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
197                     + Debug.getCallers(3));
198             return;
199         }
200 
201         if (mService.mWaitingForConfig) {
202             // Our configuration has changed (most likely rotation), but we
203             // don't yet have the complete configuration to report to
204             // applications.  Don't do any window layout until we have it.
205             return;
206         }
207 
208         if (!mService.mDisplayReady) {
209             // Not yet initialized, nothing to do.
210             return;
211         }
212 
213         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
214         mInLayout = true;
215 
216         boolean recoveringMemory = false;
217         if (!mService.mForceRemoves.isEmpty()) {
218             recoveringMemory = true;
219             // Wait a little bit for things to settle down, and off we go.
220             while (!mService.mForceRemoves.isEmpty()) {
221                 WindowState ws = mService.mForceRemoves.remove(0);
222                 Slog.i(TAG, "Force removing: " + ws);
223                 mService.removeWindowInnerLocked(ws);
224             }
225             Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
226             Object tmp = new Object();
227             synchronized (tmp) {
228                 try {
229                     tmp.wait(250);
230                 } catch (InterruptedException e) {
231                 }
232             }
233         }
234 
235         try {
236             performSurfacePlacementInner(recoveringMemory);
237 
238             mInLayout = false;
239 
240             if (mService.needsLayout()) {
241                 if (++mLayoutRepeatCount < 6) {
242                     requestTraversal();
243                 } else {
244                     Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
245                     mLayoutRepeatCount = 0;
246                 }
247             } else {
248                 mLayoutRepeatCount = 0;
249             }
250 
251             if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
252                 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
253                 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
254             }
255         } catch (RuntimeException e) {
256             mInLayout = false;
257             Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
258         }
259 
260         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
261     }
262 
debugLayoutRepeats(final String msg, int pendingLayoutChanges)263     void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
264         if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
265             Slog.v(TAG, "Layouts looping: " + msg +
266                     ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
267         }
268     }
269 
270     // "Something has changed!  Let's make it correct now."
performSurfacePlacementInner(boolean recoveringMemory)271     private void performSurfacePlacementInner(boolean recoveringMemory) {
272         if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
273                 + Debug.getCallers(3));
274 
275         int i;
276         boolean updateInputWindowsNeeded = false;
277 
278         if (mService.mFocusMayChange) {
279             mService.mFocusMayChange = false;
280             updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
281                     UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
282         }
283 
284         // Initialize state of exiting tokens.
285         final int numDisplays = mService.mDisplayContents.size();
286         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
287             final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
288             for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
289                 displayContent.mExitingTokens.get(i).hasVisible = false;
290             }
291         }
292 
293         for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
294             // Initialize state of exiting applications.
295             final AppTokenList exitingAppTokens =
296                     mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
297             for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
298                 exitingAppTokens.get(tokenNdx).hasVisible = false;
299             }
300         }
301 
302         mHoldScreen = null;
303         mHoldScreenWindow = null;
304         mObsuringWindow = null;
305         mScreenBrightness = -1;
306         mButtonBrightness = -1;
307         mUserActivityTimeout = -1;
308         mObscureApplicationContentOnSecondaryDisplays = false;
309         mSustainedPerformanceModeCurrent = false;
310         mService.mTransactionSequence++;
311 
312         final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
313         final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
314         final int defaultDw = defaultInfo.logicalWidth;
315         final int defaultDh = defaultInfo.logicalHeight;
316 
317         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
318                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
319         SurfaceControl.openTransaction();
320         try {
321             applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
322         } catch (RuntimeException e) {
323             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
324         } finally {
325             SurfaceControl.closeTransaction();
326             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
327                     "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
328         }
329 
330         final WindowList defaultWindows = defaultDisplay.getWindowList();
331 
332         // If we are ready to perform an app transition, check through
333         // all of the app tokens to be shown and see if they are ready
334         // to go.
335         if (mService.mAppTransition.isReady()) {
336             defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
337             if (DEBUG_LAYOUT_REPEATS)
338                 debugLayoutRepeats("after handleAppTransitionReadyLocked",
339                         defaultDisplay.pendingLayoutChanges);
340         }
341 
342         if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
343             // We have finished the animation of an app transition.  To do
344             // this, we have delayed a lot of operations like showing and
345             // hiding apps, moving apps in Z-order, etc.  The app token list
346             // reflects the correct Z-order, but the window list may now
347             // be out of sync with it.  So here we will just rebuild the
348             // entire app window list.  Fun!
349             defaultDisplay.pendingLayoutChanges |=
350                     mService.handleAnimatingStoppedAndTransitionLocked();
351             if (DEBUG_LAYOUT_REPEATS)
352                 debugLayoutRepeats("after handleAnimStopAndXitionLock",
353                         defaultDisplay.pendingLayoutChanges);
354         }
355 
356         if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
357                 && !mService.mAppTransition.isReady()) {
358             // At this point, there was a window with a wallpaper that
359             // was force hiding other windows behind it, but now it
360             // is going away.  This may be simple -- just animate
361             // away the wallpaper and its window -- or it may be
362             // hard -- the wallpaper now needs to be shown behind
363             // something that was hidden.
364             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
365             if (DEBUG_LAYOUT_REPEATS)
366                 debugLayoutRepeats("after animateAwayWallpaperLocked",
367                         defaultDisplay.pendingLayoutChanges);
368         }
369         mWallpaperForceHidingChanged = false;
370 
371         if (mWallpaperMayChange) {
372             if (DEBUG_WALLPAPER_LIGHT)
373                 Slog.v(TAG, "Wallpaper may change!  Adjusting");
374             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
375             if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
376                     defaultDisplay.pendingLayoutChanges);
377         }
378 
379         if (mService.mFocusMayChange) {
380             mService.mFocusMayChange = false;
381             if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
382                     false /*updateInputWindows*/)) {
383                 updateInputWindowsNeeded = true;
384                 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
385             }
386         }
387 
388         if (mService.needsLayout()) {
389             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
390             if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
391                     defaultDisplay.pendingLayoutChanges);
392         }
393 
394         for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
395             WindowState win = mService.mResizingWindows.get(i);
396             if (win.mAppFreezing) {
397                 // Don't remove this window until rotation has completed.
398                 continue;
399             }
400             // Discard the saved surface if window size is changed, it can't be reused.
401             if (win.mAppToken != null) {
402                 win.mAppToken.destroySavedSurfaces();
403             }
404             win.reportResized();
405             mService.mResizingWindows.remove(i);
406         }
407 
408         if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
409                 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
410         if (mOrientationChangeComplete) {
411             if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
412                 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
413                 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
414                 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
415             }
416             mService.stopFreezingDisplayLocked();
417         }
418 
419         // Destroy the surface of any windows that are no longer visible.
420         boolean wallpaperDestroyed = false;
421         i = mService.mDestroySurface.size();
422         if (i > 0) {
423             do {
424                 i--;
425                 WindowState win = mService.mDestroySurface.get(i);
426                 win.mDestroying = false;
427                 if (mService.mInputMethodWindow == win) {
428                     mService.mInputMethodWindow = null;
429                 }
430                 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
431                     wallpaperDestroyed = true;
432                 }
433                 win.destroyOrSaveSurface();
434             } while (i > 0);
435             mService.mDestroySurface.clear();
436         }
437 
438         // Time to remove any exiting tokens?
439         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
440             final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
441             ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
442             for (i = exitingTokens.size() - 1; i >= 0; i--) {
443                 WindowToken token = exitingTokens.get(i);
444                 if (!token.hasVisible) {
445                     exitingTokens.remove(i);
446                     if (token.windowType == TYPE_WALLPAPER) {
447                         mWallpaperControllerLocked.removeWallpaperToken(token);
448                     }
449                 }
450             }
451         }
452 
453         // Time to remove any exiting applications?
454         for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
455             // Initialize state of exiting applications.
456             final AppTokenList exitingAppTokens =
457                     mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
458             for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
459                 AppWindowToken token = exitingAppTokens.get(i);
460                 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
461                         (!token.mIsExiting || token.allAppWindows.isEmpty())) {
462                     // Make sure there is no animation running on this token,
463                     // so any windows associated with it will be removed as
464                     // soon as their animations are complete
465                     token.mAppAnimator.clearAnimation();
466                     token.mAppAnimator.animating = false;
467                     if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
468                             "performLayout: App token exiting now removed" + token);
469                     token.removeAppFromTaskLocked();
470                 }
471             }
472         }
473 
474         if (wallpaperDestroyed) {
475             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
476             defaultDisplay.layoutNeeded = true;
477         }
478 
479         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
480             final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
481             if (displayContent.pendingLayoutChanges != 0) {
482                 displayContent.layoutNeeded = true;
483             }
484         }
485 
486         // Finally update all input windows now that the window changes have stabilized.
487         mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
488 
489         mService.setHoldScreenLocked(mHoldScreen);
490         if (!mService.mDisplayFrozen) {
491             if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
492                 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
493             } else {
494                 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
495                         toBrightnessOverride(mScreenBrightness));
496             }
497             if (mButtonBrightness < 0
498                     || mButtonBrightness > 1.0f) {
499                 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
500             } else {
501                 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
502                         toBrightnessOverride(mButtonBrightness));
503             }
504             mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
505                     mUserActivityTimeout);
506         }
507 
508         if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
509             mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
510             mService.mPowerManagerInternal.powerHint(
511                     mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
512                     (mSustainedPerformanceModeEnabled ? 1 : 0));
513         }
514 
515         if (mService.mTurnOnScreen) {
516             if (mService.mAllowTheaterModeWakeFromLayout
517                     || Settings.Global.getInt(mService.mContext.getContentResolver(),
518                         Settings.Global.THEATER_MODE_ON, 0) == 0) {
519                 if (DEBUG_VISIBILITY || DEBUG_POWER) {
520                     Slog.v(TAG, "Turning screen on after layout!");
521                 }
522                 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
523                         "android.server.wm:TURN_ON");
524             }
525             mService.mTurnOnScreen = false;
526         }
527 
528         if (mUpdateRotation) {
529             if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
530             if (mService.updateRotationUncheckedLocked(false)) {
531                 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
532             } else {
533                 mUpdateRotation = false;
534             }
535         }
536 
537         if (mService.mWaitingForDrawnCallback != null ||
538                 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
539                         !mUpdateRotation)) {
540             mService.checkDrawnWindowsLocked();
541         }
542 
543         final int N = mService.mPendingRemove.size();
544         if (N > 0) {
545             if (mService.mPendingRemoveTmp.length < N) {
546                 mService.mPendingRemoveTmp = new WindowState[N+10];
547             }
548             mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
549             mService.mPendingRemove.clear();
550             DisplayContentList displayList = new DisplayContentList();
551             for (i = 0; i < N; i++) {
552                 WindowState w = mService.mPendingRemoveTmp[i];
553                 mService.removeWindowInnerLocked(w);
554                 final DisplayContent displayContent = w.getDisplayContent();
555                 if (displayContent != null && !displayList.contains(displayContent)) {
556                     displayList.add(displayContent);
557                 }
558             }
559 
560             for (DisplayContent displayContent : displayList) {
561                 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
562                 displayContent.layoutNeeded = true;
563             }
564         }
565 
566         // Remove all deferred displays stacks, tasks, and activities.
567         for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
568             mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
569         }
570 
571         if (updateInputWindowsNeeded) {
572             mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
573         }
574         mService.setFocusTaskRegionLocked();
575 
576         // Check to see if we are now in a state where the screen should
577         // be enabled, because the window obscured flags have changed.
578         mService.enableScreenIfNeededLocked();
579 
580         mService.scheduleAnimationLocked();
581         mService.mWindowPlacerLocked.destroyPendingSurfaces();
582 
583         if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
584                 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
585     }
586 
applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays, int defaultDw, int defaultDh)587     private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
588             int defaultDw, int defaultDh) {
589         if (mService.mWatermark != null) {
590             mService.mWatermark.positionSurface(defaultDw, defaultDh);
591         }
592         if (mService.mStrictModeFlash != null) {
593             mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
594         }
595         if (mService.mCircularDisplayMask != null) {
596             mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
597                     mService.mRotation);
598         }
599         if (mService.mEmulatorDisplayOverlay != null) {
600             mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
601                     mService.mRotation);
602         }
603 
604         boolean focusDisplayed = false;
605 
606         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
607             final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
608             boolean updateAllDrawn = false;
609             WindowList windows = displayContent.getWindowList();
610             DisplayInfo displayInfo = displayContent.getDisplayInfo();
611             final int displayId = displayContent.getDisplayId();
612             final int dw = displayInfo.logicalWidth;
613             final int dh = displayInfo.logicalHeight;
614             final int innerDw = displayInfo.appWidth;
615             final int innerDh = displayInfo.appHeight;
616             final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
617 
618             // Reset for each display.
619             mDisplayHasContent = false;
620             mPreferredRefreshRate = 0;
621             mPreferredModeId = 0;
622 
623             int repeats = 0;
624             do {
625                 repeats++;
626                 if (repeats > 6) {
627                     Slog.w(TAG, "Animation repeat aborted after too many iterations");
628                     displayContent.layoutNeeded = false;
629                     break;
630                 }
631 
632                 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
633                         "On entry to LockedInner", displayContent.pendingLayoutChanges);
634 
635                 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
636                         mWallpaperControllerLocked.adjustWallpaperWindows()) {
637                     mService.mLayersController.assignLayersLocked(windows);
638                     displayContent.layoutNeeded = true;
639                 }
640 
641                 if (isDefaultDisplay
642                         && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
643                     if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
644                     if (mService.updateOrientationFromAppTokensLocked(true)) {
645                         displayContent.layoutNeeded = true;
646                         mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
647                     }
648                 }
649 
650                 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
651                     displayContent.layoutNeeded = true;
652                 }
653 
654                 // FIRST LOOP: Perform a layout, if needed.
655                 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
656                     performLayoutLockedInner(displayContent, repeats == 1,
657                             false /* updateInputWindows */);
658                 } else {
659                     Slog.w(TAG, "Layout repeat skipped after too many iterations");
660                 }
661 
662                 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
663                 // it is animating.
664                 displayContent.pendingLayoutChanges = 0;
665 
666                 if (isDefaultDisplay) {
667                     mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
668                     for (int i = windows.size() - 1; i >= 0; i--) {
669                         WindowState w = windows.get(i);
670                         if (w.mHasSurface) {
671                             mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
672                                     w.mAttachedWindow);
673                         }
674                     }
675                     displayContent.pendingLayoutChanges |=
676                             mService.mPolicy.finishPostLayoutPolicyLw();
677                     if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
678                             displayContent.pendingLayoutChanges);
679                 }
680             } while (displayContent.pendingLayoutChanges != 0);
681 
682             mObscured = false;
683             mSyswin = false;
684             displayContent.resetDimming();
685 
686             // Only used if default window
687             final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
688 
689             for (int i = windows.size() - 1; i >= 0; i--) {
690                 WindowState w = windows.get(i);
691                 final Task task = w.getTask();
692                 final boolean obscuredChanged = w.mObscured != mObscured;
693 
694                 // Update effect.
695                 w.mObscured = mObscured;
696                 if (!mObscured) {
697                     handleNotObscuredLocked(w, displayInfo);
698                 }
699 
700                 w.applyDimLayerIfNeeded();
701 
702                 if (isDefaultDisplay && obscuredChanged
703                         && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
704                     // This is the wallpaper target and its obscured state
705                     // changed... make sure the current wallaper's visibility
706                     // has been updated accordingly.
707                     mWallpaperControllerLocked.updateWallpaperVisibility();
708                 }
709 
710                 final WindowStateAnimator winAnimator = w.mWinAnimator;
711 
712                 // If the window has moved due to its containing content frame changing, then
713                 // notify the listeners and optionally animate it. Simply checking a change of
714                 // position is not enough, because being move due to dock divider is not a trigger
715                 // for animation.
716                 if (w.hasMoved()) {
717                     // Frame has moved, containing content frame has also moved, and we're not
718                     // currently animating... let's do something.
719                     final int left = w.mFrame.left;
720                     final int top = w.mFrame.top;
721                     final boolean adjustedForMinimizedDockOrIme = task != null
722                                 && (task.mStack.isAdjustedForMinimizedDockedStack()
723                                     || task.mStack.isAdjustedForIme());
724                     if (mService.okToDisplay()) {
725                         if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
726                                 && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
727                                 && (task == null || w.getTask().mStack.hasMovementAnimations())
728                                 && !w.mWinAnimator.mLastHidden) {
729                             winAnimator.setMoveAnimation(left, top);
730                         }
731                     }
732 
733                     //TODO (multidisplay): Accessibility supported only for the default display.
734                     if (mService.mAccessibilityController != null
735                             && displayId == Display.DEFAULT_DISPLAY) {
736                         mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
737                     }
738 
739                     try {
740                         w.mClient.moved(left, top);
741                     } catch (RemoteException e) {
742                     }
743                     w.mMovedByResize = false;
744                 }
745 
746                 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
747                 w.mContentChanged = false;
748 
749                 // Moved from updateWindowsAndWallpaperLocked().
750                 if (w.mHasSurface) {
751                     // Take care of the window being ready to display.
752                     final boolean committed = winAnimator.commitFinishDrawingLocked();
753                     if (isDefaultDisplay && committed) {
754                         if (w.mAttrs.type == TYPE_DREAM) {
755                             // HACK: When a dream is shown, it may at that
756                             // point hide the lock screen.  So we need to
757                             // redo the layout to let the phone window manager
758                             // make this happen.
759                             displayContent.pendingLayoutChanges |=
760                                     FINISH_LAYOUT_REDO_LAYOUT;
761                             if (DEBUG_LAYOUT_REPEATS) {
762                                 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
763                                         displayContent.pendingLayoutChanges);
764                             }
765                         }
766                         if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
767                             if (DEBUG_WALLPAPER_LIGHT)
768                                 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
769                             mWallpaperMayChange = true;
770                             displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
771                             if (DEBUG_LAYOUT_REPEATS) {
772                                 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
773                                         displayContent.pendingLayoutChanges);
774                             }
775                         }
776                     }
777                     if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
778                         // Updates the shown frame before we set up the surface. This is needed
779                         // because the resizing could change the top-left position (in addition to
780                         // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
781                         // position the surface.
782                         //
783                         // If an animation is being started, we can't call this method because the
784                         // animation hasn't processed its initial transformation yet, but in general
785                         // we do want to update the position if the window is animating.
786                         winAnimator.computeShownFrameLocked();
787                     }
788                     winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
789                 }
790 
791                 final AppWindowToken atoken = w.mAppToken;
792                 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
793                     Slog.d(TAG, "updateWindows: starting " + w
794                             + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
795                             + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
796                 }
797                 if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
798                         || atoken.mAppAnimator.freezingScreen)) {
799                     if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
800                         atoken.lastTransactionSequence = mService.mTransactionSequence;
801                         atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
802                         atoken.numInterestingWindowsExcludingSaved = 0;
803                         atoken.numDrawnWindowsExclusingSaved = 0;
804                         atoken.startingDisplayed = false;
805                     }
806                     if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
807                         if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
808                             Slog.v(TAG, "Eval win " + w + ": isDrawn="
809                                     + w.isDrawnLw()
810                                     + ", isAnimationSet=" + winAnimator.isAnimationSet());
811                             if (!w.isDrawnLw()) {
812                                 Slog.v(TAG, "Not displayed: s="
813                                         + winAnimator.mSurfaceController
814                                         + " pv=" + w.mPolicyVisibility
815                                         + " mDrawState=" + winAnimator.drawStateToString()
816                                         + " ah=" + w.mAttachedHidden
817                                         + " th=" + atoken.hiddenRequested
818                                         + " a=" + winAnimator.mAnimating);
819                             }
820                         }
821                         if (w != atoken.startingWindow) {
822                             if (w.isInteresting()) {
823                                 atoken.numInterestingWindows++;
824                                 if (w.isDrawnLw()) {
825                                     atoken.numDrawnWindows++;
826                                     if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
827                                         Slog.v(TAG, "tokenMayBeDrawn: " + atoken
828                                                 + " w=" + w + " numInteresting="
829                                                 + atoken.numInterestingWindows
830                                                 + " freezingScreen="
831                                                 + atoken.mAppAnimator.freezingScreen
832                                                 + " mAppFreezing=" + w.mAppFreezing);
833                                     updateAllDrawn = true;
834                                 }
835                             }
836                         } else if (w.isDrawnLw()) {
837                             mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
838                             atoken.startingDisplayed = true;
839                         }
840                     }
841                     if (!atoken.allDrawnExcludingSaved
842                             && w.mightAffectAllDrawn(true /* visibleOnly */)) {
843                         if (w != atoken.startingWindow && w.isInteresting()) {
844                             atoken.numInterestingWindowsExcludingSaved++;
845                             if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
846                                 atoken.numDrawnWindowsExclusingSaved++;
847                                 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
848                                     Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
849                                             + " w=" + w + " numInteresting="
850                                             + atoken.numInterestingWindowsExcludingSaved
851                                             + " freezingScreen="
852                                             + atoken.mAppAnimator.freezingScreen
853                                             + " mAppFreezing=" + w.mAppFreezing);
854                                 updateAllDrawn = true;
855                             }
856                         }
857                     }
858                 }
859 
860                 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
861                         && w.isDisplayedLw()) {
862                     focusDisplayed = true;
863                 }
864 
865                 mService.updateResizingWindows(w);
866             }
867 
868             mService.mDisplayManagerInternal.setDisplayProperties(displayId,
869                     mDisplayHasContent,
870                     mPreferredRefreshRate,
871                     mPreferredModeId,
872                     true /* inTraversal, must call performTraversalInTrans... below */);
873 
874             mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
875 
876             if (updateAllDrawn) {
877                 updateAllDrawnLocked(displayContent);
878             }
879         }
880 
881         if (focusDisplayed) {
882             mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
883         }
884 
885         // Give the display manager a chance to adjust properties
886         // like display rotation if it needs to.
887         mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
888     }
889 
isInLayout()890     boolean isInLayout() {
891         return mInLayout;
892     }
893 
performLayoutLockedInner(final DisplayContent displayContent, boolean initial, boolean updateInputWindows)894     final void performLayoutLockedInner(final DisplayContent displayContent,
895             boolean initial, boolean updateInputWindows) {
896         if (!displayContent.layoutNeeded) {
897             return;
898         }
899         displayContent.layoutNeeded = false;
900         WindowList windows = displayContent.getWindowList();
901         boolean isDefaultDisplay = displayContent.isDefaultDisplay;
902 
903         DisplayInfo displayInfo = displayContent.getDisplayInfo();
904         final int dw = displayInfo.logicalWidth;
905         final int dh = displayInfo.logicalHeight;
906 
907         if (mService.mInputConsumer != null) {
908             mService.mInputConsumer.layout(dw, dh);
909         }
910 
911         if (mService.mWallpaperInputConsumer != null) {
912             mService.mWallpaperInputConsumer.layout(dw, dh);
913         }
914 
915         final int N = windows.size();
916         int i;
917 
918         if (DEBUG_LAYOUT) {
919             Slog.v(TAG, "-------------------------------------");
920             Slog.v(TAG, "performLayout: needed="
921                     + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
922         }
923 
924         mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
925                 mService.mCurConfiguration.uiMode);
926         if (isDefaultDisplay) {
927             // Not needed on non-default displays.
928             mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
929             mService.mScreenRect.set(0, 0, dw, dh);
930         }
931 
932         mService.mPolicy.getContentRectLw(mTmpContentRect);
933         displayContent.resize(mTmpContentRect);
934 
935         int seq = mService.mLayoutSeq+1;
936         if (seq < 0) seq = 0;
937         mService.mLayoutSeq = seq;
938 
939         boolean behindDream = false;
940 
941         // First perform layout of any root windows (not attached
942         // to another window).
943         int topAttached = -1;
944         for (i = N-1; i >= 0; i--) {
945             final WindowState win = windows.get(i);
946 
947             // Don't do layout of a window if it is not visible, or
948             // soon won't be visible, to avoid wasting time and funky
949             // changes while a window is animating away.
950             final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
951                     || win.isGoneForLayoutLw();
952 
953             if (DEBUG_LAYOUT && !win.mLayoutAttached) {
954                 Slog.v(TAG, "1ST PASS " + win
955                         + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
956                         + " mLayoutAttached=" + win.mLayoutAttached
957                         + " screen changed=" + win.isConfigChanged());
958                 final AppWindowToken atoken = win.mAppToken;
959                 if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
960                         + win.mViewVisibility + " mRelayoutCalled="
961                         + win.mRelayoutCalled + " hidden="
962                         + win.mRootToken.hidden + " hiddenRequested="
963                         + (atoken != null && atoken.hiddenRequested)
964                         + " mAttachedHidden=" + win.mAttachedHidden);
965                 else Slog.v(TAG, "  VIS: mViewVisibility="
966                         + win.mViewVisibility + " mRelayoutCalled="
967                         + win.mRelayoutCalled + " hidden="
968                         + win.mRootToken.hidden + " hiddenRequested="
969                         + (atoken != null && atoken.hiddenRequested)
970                         + " mAttachedHidden=" + win.mAttachedHidden);
971             }
972 
973             // If this view is GONE, then skip it -- keep the current
974             // frame, and let the caller know so they can ignore it
975             // if they want.  (We do the normal layout for INVISIBLE
976             // windows, since that means "perform layout as normal,
977             // just don't display").
978             if (!gone || !win.mHaveFrame || win.mLayoutNeeded
979                     || ((win.isConfigChanged() || win.setReportResizeHints())
980                             && !win.isGoneForLayoutLw() &&
981                             ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
982                             (win.mHasSurface && win.mAppToken != null &&
983                             win.mAppToken.layoutConfigChanges)))) {
984                 if (!win.mLayoutAttached) {
985                     if (initial) {
986                         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
987                         win.mContentChanged = false;
988                     }
989                     if (win.mAttrs.type == TYPE_DREAM) {
990                         // Don't layout windows behind a dream, so that if it
991                         // does stuff like hide the status bar we won't get a
992                         // bad transition when it goes away.
993                         behindDream = true;
994                     }
995                     win.mLayoutNeeded = false;
996                     win.prelayout();
997                     mService.mPolicy.layoutWindowLw(win, null);
998                     win.mLayoutSeq = seq;
999 
1000                     // Window frames may have changed. Update dim layer with the new bounds.
1001                     final Task task = win.getTask();
1002                     if (task != null) {
1003                         displayContent.mDimLayerController.updateDimLayer(task);
1004                     }
1005 
1006                     if (DEBUG_LAYOUT) Slog.v(TAG,
1007                             "  LAYOUT: mFrame="
1008                             + win.mFrame + " mContainingFrame="
1009                             + win.mContainingFrame + " mDisplayFrame="
1010                             + win.mDisplayFrame);
1011                 } else {
1012                     if (topAttached < 0) topAttached = i;
1013                 }
1014             }
1015         }
1016 
1017         boolean attachedBehindDream = false;
1018 
1019         // Now perform layout of attached windows, which usually
1020         // depend on the position of the window they are attached to.
1021         // XXX does not deal with windows that are attached to windows
1022         // that are themselves attached.
1023         for (i = topAttached; i >= 0; i--) {
1024             final WindowState win = windows.get(i);
1025 
1026             if (win.mLayoutAttached) {
1027                 if (DEBUG_LAYOUT) Slog.v(TAG,
1028                         "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
1029                         + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
1030                 // If this view is GONE, then skip it -- keep the current
1031                 // frame, and let the caller know so they can ignore it
1032                 // if they want.  (We do the normal layout for INVISIBLE
1033                 // windows, since that means "perform layout as normal,
1034                 // just don't display").
1035                 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
1036                     continue;
1037                 }
1038                 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
1039                         || !win.mHaveFrame || win.mLayoutNeeded) {
1040                     if (initial) {
1041                         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
1042                         win.mContentChanged = false;
1043                     }
1044                     win.mLayoutNeeded = false;
1045                     win.prelayout();
1046                     mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
1047                     win.mLayoutSeq = seq;
1048                     if (DEBUG_LAYOUT) Slog.v(TAG,
1049                             "  LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
1050                             + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
1051                 }
1052             } else if (win.mAttrs.type == TYPE_DREAM) {
1053                 // Don't layout windows behind a dream, so that if it
1054                 // does stuff like hide the status bar we won't get a
1055                 // bad transition when it goes away.
1056                 attachedBehindDream = behindDream;
1057             }
1058         }
1059 
1060         // Window frames may have changed. Tell the input dispatcher about it.
1061         mService.mInputMonitor.setUpdateInputWindowsNeededLw();
1062         if (updateInputWindows) {
1063             mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
1064         }
1065 
1066         mService.mPolicy.finishLayoutLw();
1067         mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
1068     }
1069 
1070     /**
1071      * @param windows List of windows on default display.
1072      * @return bitmap indicating if another pass through layout must be made.
1073      */
handleAppTransitionReadyLocked(WindowList windows)1074     private int handleAppTransitionReadyLocked(WindowList windows) {
1075         int appsCount = mService.mOpeningApps.size();
1076         if (!transitionGoodToGo(appsCount)) {
1077             return 0;
1078         }
1079         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
1080 
1081         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
1082         int transit = mService.mAppTransition.getAppTransition();
1083         if (mService.mSkipAppTransitionAnimation) {
1084             transit = AppTransition.TRANSIT_UNSET;
1085         }
1086         mService.mSkipAppTransitionAnimation = false;
1087         mService.mNoAnimationNotifyOnTransitionFinished.clear();
1088 
1089         mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
1090 
1091         mService.rebuildAppWindowListLocked();
1092 
1093         mWallpaperMayChange = false;
1094 
1095         // The top-most window will supply the layout params,
1096         // and we will determine it below.
1097         LayoutParams animLp = null;
1098         int bestAnimLayer = -1;
1099         boolean fullscreenAnim = false;
1100         boolean voiceInteraction = false;
1101 
1102         int i;
1103         for (i = 0; i < appsCount; i++) {
1104             final AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1105             // Clearing the mAnimatingExit flag before entering animation. It's set to
1106             // true if app window is removed, or window relayout to invisible.
1107             // This also affects window visibility. We need to clear it *before*
1108             // maybeUpdateTransitToWallpaper() as the transition selection depends on
1109             // wallpaper target visibility.
1110             wtoken.clearAnimatingFlags();
1111 
1112         }
1113         // Adjust wallpaper before we pull the lower/upper target, since pending changes
1114         // (like the clearAnimatingFlags() above) might affect wallpaper target result.
1115         final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1116         if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
1117                 mWallpaperControllerLocked.adjustWallpaperWindows()) {
1118             mService.mLayersController.assignLayersLocked(windows);
1119             displayContent.layoutNeeded = true;
1120         }
1121 
1122         final WindowState lowerWallpaperTarget =
1123                 mWallpaperControllerLocked.getLowerWallpaperTarget();
1124         final WindowState upperWallpaperTarget =
1125                 mWallpaperControllerLocked.getUpperWallpaperTarget();
1126 
1127         boolean openingAppHasWallpaper = false;
1128         boolean closingAppHasWallpaper = false;
1129         final AppWindowToken lowerWallpaperAppToken;
1130         final AppWindowToken upperWallpaperAppToken;
1131         if (lowerWallpaperTarget == null) {
1132             lowerWallpaperAppToken = upperWallpaperAppToken = null;
1133         } else {
1134             lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1135             upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1136         }
1137 
1138         // Do a first pass through the tokens for two
1139         // things:
1140         // (1) Determine if both the closing and opening
1141         // app token sets are wallpaper targets, in which
1142         // case special animations are needed
1143         // (since the wallpaper needs to stay static
1144         // behind them).
1145         // (2) Find the layout params of the top-most
1146         // application window in the tokens, which is
1147         // what will control the animation theme.
1148         final int closingAppsCount = mService.mClosingApps.size();
1149         appsCount = closingAppsCount + mService.mOpeningApps.size();
1150         for (i = 0; i < appsCount; i++) {
1151             final AppWindowToken wtoken;
1152             if (i < closingAppsCount) {
1153                 wtoken = mService.mClosingApps.valueAt(i);
1154                 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1155                     closingAppHasWallpaper = true;
1156                 }
1157             } else {
1158                 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1159                 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1160                     openingAppHasWallpaper = true;
1161                 }
1162             }
1163 
1164             voiceInteraction |= wtoken.voiceInteraction;
1165 
1166             if (wtoken.appFullscreen) {
1167                 WindowState ws = wtoken.findMainWindow();
1168                 if (ws != null) {
1169                     animLp = ws.mAttrs;
1170                     bestAnimLayer = ws.mLayer;
1171                     fullscreenAnim = true;
1172                 }
1173             } else if (!fullscreenAnim) {
1174                 WindowState ws = wtoken.findMainWindow();
1175                 if (ws != null) {
1176                     if (ws.mLayer > bestAnimLayer) {
1177                         animLp = ws.mAttrs;
1178                         bestAnimLayer = ws.mLayer;
1179                     }
1180                 }
1181             }
1182         }
1183 
1184         transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1185                 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1186 
1187         // If all closing windows are obscured, then there is
1188         // no need to do an animation.  This is the case, for
1189         // example, when this transition is being done behind
1190         // the lock screen.
1191         if (!mService.mPolicy.allowAppAnimationsLw()) {
1192             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1193                     "Animations disallowed by keyguard or dream.");
1194             animLp = null;
1195         }
1196 
1197         processApplicationsAnimatingInPlace(transit);
1198 
1199         mTmpLayerAndToken.token = null;
1200         handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1201         final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1202         final int topClosingLayer = mTmpLayerAndToken.layer;
1203 
1204         final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1205                 animLp, voiceInteraction, topClosingLayer);
1206 
1207         mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
1208 
1209         final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
1210                 topOpeningApp.mAppAnimator;
1211         final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1212                 topClosingApp.mAppAnimator;
1213 
1214         mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1215                 mService.mOpeningApps, mService.mClosingApps);
1216         mService.mAppTransition.postAnimationCallback();
1217         mService.mAppTransition.clear();
1218 
1219         mService.mOpeningApps.clear();
1220         mService.mClosingApps.clear();
1221 
1222         // This has changed the visibility of windows, so perform
1223         // a new layout to get them all up-to-date.
1224         displayContent.layoutNeeded = true;
1225 
1226         // TODO(multidisplay): IMEs are only supported on the default display.
1227         if (windows == mService.getDefaultWindowListLocked()
1228                 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
1229             mService.mLayersController.assignLayersLocked(windows);
1230         }
1231         mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1232                 true /*updateInputWindows*/);
1233         mService.mFocusMayChange = false;
1234         mService.notifyActivityDrawnForKeyguard();
1235 
1236         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1237 
1238         return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1239     }
1240 
handleOpeningApps(int transit, LayoutParams animLp, boolean voiceInteraction, int topClosingLayer)1241     private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1242             boolean voiceInteraction, int topClosingLayer) {
1243         AppWindowToken topOpeningApp = null;
1244         final int appsCount = mService.mOpeningApps.size();
1245         for (int i = 0; i < appsCount; i++) {
1246             AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1247             final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1248             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
1249 
1250             if (!appAnimator.usingTransferredAnimation) {
1251                 appAnimator.clearThumbnail();
1252                 appAnimator.setNullAnimation();
1253             }
1254             wtoken.inPendingTransaction = false;
1255 
1256             if (!mService.setTokenVisibilityLocked(
1257                     wtoken, animLp, true, transit, false, voiceInteraction)){
1258                 // This token isn't going to be animating. Add it to the list of tokens to
1259                 // be notified of app transition complete since the notification will not be
1260                 // sent be the app window animator.
1261                 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1262             }
1263             wtoken.updateReportedVisibilityLocked();
1264             wtoken.waitingToShow = false;
1265 
1266             appAnimator.mAllAppWinAnimators.clear();
1267             final int windowsCount = wtoken.allAppWindows.size();
1268             for (int j = 0; j < windowsCount; j++) {
1269                 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1270             }
1271             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1272                     ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1273             SurfaceControl.openTransaction();
1274             try {
1275                 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
1276             } finally {
1277                 SurfaceControl.closeTransaction();
1278                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1279                         "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1280             }
1281             mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1282 
1283             int topOpeningLayer = 0;
1284             if (animLp != null) {
1285                 int layer = -1;
1286                 for (int j = 0; j < wtoken.allAppWindows.size(); j++) {
1287                     final WindowState win = wtoken.allAppWindows.get(j);
1288                     if (win.mWinAnimator.mAnimLayer > layer) {
1289                         layer = win.mWinAnimator.mAnimLayer;
1290                     }
1291                 }
1292                 if (topOpeningApp == null || layer > topOpeningLayer) {
1293                     topOpeningApp = wtoken;
1294                     topOpeningLayer = layer;
1295                 }
1296             }
1297             if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1298                 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1299             }
1300         }
1301         return topOpeningApp;
1302     }
1303 
handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction, LayerAndToken layerAndToken)1304     private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1305             LayerAndToken layerAndToken) {
1306         final int appsCount;
1307         appsCount = mService.mClosingApps.size();
1308         for (int i = 0; i < appsCount; i++) {
1309             AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1310 
1311             // If we still have some windows animating with saved surfaces that's
1312             // either invisible or already removed, mark them exiting so that they
1313             // are disposed of after the exit animation. These are not supposed to
1314             // be shown, or are delayed removal until app is actually drawn (in which
1315             // case the window will be removed after the animation).
1316             wtoken.markSavedSurfaceExiting();
1317 
1318             final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1319             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
1320             appAnimator.clearThumbnail();
1321             appAnimator.setNullAnimation();
1322             wtoken.inPendingTransaction = false;
1323             mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1324                     voiceInteraction);
1325             wtoken.updateReportedVisibilityLocked();
1326             // Force the allDrawn flag, because we want to start
1327             // this guy's animations regardless of whether it's
1328             // gotten drawn.
1329             wtoken.allDrawn = true;
1330             wtoken.deferClearAllDrawn = false;
1331             // Ensure that apps that are mid-starting are also scheduled to have their
1332             // starting windows removed after the animation is complete
1333             if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
1334                 mService.scheduleRemoveStartingWindowLocked(wtoken);
1335             }
1336             mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1337 
1338             if (animLp != null) {
1339                 int layer = -1;
1340                 for (int j = 0; j < wtoken.windows.size(); j++) {
1341                     WindowState win = wtoken.windows.get(j);
1342                     if (win.mWinAnimator.mAnimLayer > layer) {
1343                         layer = win.mWinAnimator.mAnimLayer;
1344                     }
1345                 }
1346                 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1347                     layerAndToken.token = wtoken;
1348                     layerAndToken.layer = layer;
1349                 }
1350             }
1351             if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1352                 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1353             }
1354         }
1355     }
1356 
transitionGoodToGo(int appsCount)1357     private boolean transitionGoodToGo(int appsCount) {
1358         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1359                 "Checking " + appsCount + " opening apps (frozen="
1360                         + mService.mDisplayFrozen + " timeout="
1361                         + mService.mAppTransition.isTimeout() + ")...");
1362         final ScreenRotationAnimation screenRotationAnimation =
1363             mService.mAnimator.getScreenRotationAnimationLocked(
1364                     Display.DEFAULT_DISPLAY);
1365 
1366         int reason = APP_TRANSITION_TIMEOUT;
1367         if (!mService.mAppTransition.isTimeout()) {
1368             // Imagine the case where we are changing orientation due to an app transition, but a previous
1369             // orientation change is still in progress. We won't process the orientation change
1370             // for our transition because we need to wait for the rotation animation to finish.
1371             // If we start the app transition at this point, we will interrupt it halfway with a new rotation
1372             // animation after the old one finally finishes. It's better to defer the
1373             // app transition.
1374             if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
1375                     mService.rotationNeedsUpdateLocked()) {
1376                 if (DEBUG_APP_TRANSITIONS) {
1377                     Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
1378                 }
1379                 return false;
1380             }
1381             for (int i = 0; i < appsCount; i++) {
1382                 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1383                 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1384                         "Check opening app=" + wtoken + ": allDrawn="
1385                         + wtoken.allDrawn + " startingDisplayed="
1386                         + wtoken.startingDisplayed + " startingMoved="
1387                         + wtoken.startingMoved + " isRelaunching()="
1388                         + wtoken.isRelaunching());
1389 
1390                 if (wtoken.isRelaunching()) {
1391                     return false;
1392                 }
1393 
1394                 final boolean drawnBeforeRestoring = wtoken.allDrawn;
1395                 wtoken.restoreSavedSurfaces();
1396 
1397                 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1398                     return false;
1399                 }
1400                 if (wtoken.allDrawn) {
1401                     reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1402                             : APP_TRANSITION_SAVED_SURFACE;
1403                 } else {
1404                     reason = APP_TRANSITION_STARTING_WINDOW;
1405                 }
1406             }
1407 
1408             // We also need to wait for the specs to be fetched, if needed.
1409             if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
1410                 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
1411                 return false;
1412             }
1413 
1414             // If the wallpaper is visible, we need to check it's ready too.
1415             boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
1416                     mWallpaperControllerLocked.wallpaperTransitionReady();
1417             if (wallpaperReady) {
1418                 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1419                 return true;
1420             }
1421             return false;
1422         }
1423         mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1424         return true;
1425     }
1426 
maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper, boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget, WindowState upperWallpaperTarget)1427     private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1428             boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1429             WindowState upperWallpaperTarget) {
1430         // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1431         final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1432         final WindowState oldWallpaper =
1433                 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1434                         ? null : wallpaperTarget;
1435         final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1436         final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
1437         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1438                 "New wallpaper target=" + wallpaperTarget
1439                         + ", oldWallpaper=" + oldWallpaper
1440                         + ", lower target=" + lowerWallpaperTarget
1441                         + ", upper target=" + upperWallpaperTarget
1442                         + ", openingApps=" + openingApps
1443                         + ", closingApps=" + closingApps);
1444         mService.mAnimateWallpaperWithTarget = false;
1445         if (closingAppHasWallpaper && openingAppHasWallpaper) {
1446             if (DEBUG_APP_TRANSITIONS)
1447                 Slog.v(TAG, "Wallpaper animation!");
1448             switch (transit) {
1449                 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1450                 case AppTransition.TRANSIT_TASK_OPEN:
1451                 case AppTransition.TRANSIT_TASK_TO_FRONT:
1452                     transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1453                     break;
1454                 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1455                 case AppTransition.TRANSIT_TASK_CLOSE:
1456                 case AppTransition.TRANSIT_TASK_TO_BACK:
1457                     transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1458                     break;
1459             }
1460             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1461                     "New transit: " + AppTransition.appTransitionToString(transit));
1462         } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1463                 && !openingApps.contains(oldWallpaper.mAppToken)
1464                 && closingApps.contains(oldWallpaper.mAppToken)) {
1465             // We are transitioning from an activity with a wallpaper to one without.
1466             transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
1467             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1468                     "New transit away from wallpaper: "
1469                     + AppTransition.appTransitionToString(transit));
1470         } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1471                 openingApps.contains(wallpaperTarget.mAppToken)) {
1472             // We are transitioning from an activity without
1473             // a wallpaper to now showing the wallpaper
1474             transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
1475             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
1476                     "New transit into wallpaper: "
1477                     + AppTransition.appTransitionToString(transit));
1478         } else {
1479             mService.mAnimateWallpaperWithTarget = true;
1480         }
1481         return transit;
1482     }
1483 
1484     /**
1485      * @param w WindowState this method is applied to.
1486      * @param dispInfo info of the display that the window's obscuring state is checked against.
1487      */
handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo)1488     private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
1489         final LayoutParams attrs = w.mAttrs;
1490         final int attrFlags = attrs.flags;
1491         final boolean canBeSeen = w.isDisplayedLw();
1492         final int privateflags = attrs.privateFlags;
1493 
1494         if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
1495             // This window completely covers everything behind it,
1496             // so we want to leave all of them as undimmed (for
1497             // performance reasons).
1498             if (!mObscured) {
1499                 mObsuringWindow = w;
1500             }
1501 
1502             mObscured = true;
1503         }
1504 
1505         if (w.mHasSurface && canBeSeen) {
1506             if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1507                 mHoldScreen = w.mSession;
1508                 mHoldScreenWindow = w;
1509             } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
1510                 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
1511                         + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
1512                         + Debug.getCallers(10));
1513             }
1514             if (!mSyswin && w.mAttrs.screenBrightness >= 0
1515                     && mScreenBrightness < 0) {
1516                 mScreenBrightness = w.mAttrs.screenBrightness;
1517             }
1518             if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1519                     && mButtonBrightness < 0) {
1520                 mButtonBrightness = w.mAttrs.buttonBrightness;
1521             }
1522             if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1523                     && mUserActivityTimeout < 0) {
1524                 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1525             }
1526 
1527             final int type = attrs.type;
1528             if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
1529                     || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1530                 mSyswin = true;
1531             }
1532 
1533             // This function assumes that the contents of the default display are
1534             // processed first before secondary displays.
1535             final DisplayContent displayContent = w.getDisplayContent();
1536             if (displayContent != null && displayContent.isDefaultDisplay) {
1537                 // While a dream or keyguard is showing, obscure ordinary application
1538                 // content on secondary displays (by forcibly enabling mirroring unless
1539                 // there is other content we want to show) but still allow opaque
1540                 // keyguard dialogs to be shown.
1541                 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1542                     mObscureApplicationContentOnSecondaryDisplays = true;
1543                 }
1544                 mDisplayHasContent = true;
1545             } else if (displayContent != null &&
1546                     (!mObscureApplicationContentOnSecondaryDisplays
1547                             || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1548                 // Allow full screen keyguard presentation dialogs to be seen.
1549                 mDisplayHasContent = true;
1550             }
1551             if (mPreferredRefreshRate == 0
1552                     && w.mAttrs.preferredRefreshRate != 0) {
1553                 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1554             }
1555             if (mPreferredModeId == 0
1556                     && w.mAttrs.preferredDisplayModeId != 0) {
1557                 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1558             }
1559             if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1560                 mSustainedPerformanceModeCurrent = true;
1561             }
1562         }
1563     }
1564 
updateAllDrawnLocked(DisplayContent displayContent)1565     private void updateAllDrawnLocked(DisplayContent displayContent) {
1566         // See if any windows have been drawn, so they (and others
1567         // associated with them) can now be shown.
1568         ArrayList<TaskStack> stacks = displayContent.getStacks();
1569         for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1570             final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1571             for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1572                 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1573                 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1574                     final AppWindowToken wtoken = tokens.get(tokenNdx);
1575                     if (!wtoken.allDrawn) {
1576                         int numInteresting = wtoken.numInterestingWindows;
1577                         if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1578                             if (DEBUG_VISIBILITY)
1579                                 Slog.v(TAG, "allDrawn: " + wtoken
1580                                     + " interesting=" + numInteresting
1581                                     + " drawn=" + wtoken.numDrawnWindows);
1582                             wtoken.allDrawn = true;
1583                             // Force an additional layout pass where WindowStateAnimator#
1584                             // commitFinishDrawingLocked() will call performShowLocked().
1585                             displayContent.layoutNeeded = true;
1586                             mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1587                                     wtoken.token).sendToTarget();
1588                         }
1589                     }
1590                     if (!wtoken.allDrawnExcludingSaved) {
1591                         int numInteresting = wtoken.numInterestingWindowsExcludingSaved;
1592                         if (numInteresting > 0
1593                                 && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) {
1594                             if (DEBUG_VISIBILITY)
1595                                 Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken
1596                                     + " interesting=" + numInteresting
1597                                     + " drawn=" + wtoken.numDrawnWindowsExclusingSaved);
1598                             wtoken.allDrawnExcludingSaved = true;
1599                             displayContent.layoutNeeded = true;
1600                             if (wtoken.isAnimatingInvisibleWithSavedSurface()
1601                                     && !mService.mFinishedEarlyAnim.contains(wtoken)) {
1602                                 mService.mFinishedEarlyAnim.add(wtoken);
1603                             }
1604                         }
1605                     }
1606                 }
1607             }
1608         }
1609     }
1610 
toBrightnessOverride(float value)1611     private static int toBrightnessOverride(float value) {
1612         return (int)(value * PowerManager.BRIGHTNESS_ON);
1613     }
1614 
processApplicationsAnimatingInPlace(int transit)1615     private void processApplicationsAnimatingInPlace(int transit) {
1616         if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1617             // Find the focused window
1618             final WindowState win = mService.findFocusedWindowLocked(
1619                     mService.getDefaultDisplayContentLocked());
1620             if (win != null) {
1621                 final AppWindowToken wtoken = win.mAppToken;
1622                 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1623                 if (DEBUG_APP_TRANSITIONS)
1624                     Slog.v(TAG, "Now animating app in place " + wtoken);
1625                 appAnimator.clearThumbnail();
1626                 appAnimator.setNullAnimation();
1627                 mService.updateTokenInPlaceLocked(wtoken, transit);
1628                 wtoken.updateReportedVisibilityLocked();
1629 
1630                 appAnimator.mAllAppWinAnimators.clear();
1631                 final int N = wtoken.allAppWindows.size();
1632                 for (int j = 0; j < N; j++) {
1633                     appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1634                 }
1635                 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1636                 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
1637             }
1638         }
1639     }
1640 
createThumbnailAppAnimator(int transit, AppWindowToken appToken, int openingLayer, int closingLayer)1641     private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1642             int openingLayer, int closingLayer) {
1643         AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1644         if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1645             return;
1646         }
1647         final int taskId = appToken.mTask.mTaskId;
1648         Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1649         if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
1650             if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
1651             return;
1652         }
1653         // This thumbnail animation is very special, we need to have
1654         // an extra surface with the thumbnail included with the animation.
1655         Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1656         try {
1657             // TODO(multi-display): support other displays
1658             final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1659             final Display display = displayContent.getDisplay();
1660             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1661 
1662             // Create a new surface for the thumbnail
1663             SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1664                     "thumbnail anim", dirty.width(), dirty.height(),
1665                     PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1666             surfaceControl.setLayerStack(display.getLayerStack());
1667             if (SHOW_TRANSACTIONS) {
1668                 Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
1669             }
1670 
1671             // Draw the thumbnail onto the surface
1672             Surface drawSurface = new Surface();
1673             drawSurface.copyFrom(surfaceControl);
1674             Canvas c = drawSurface.lockCanvas(dirty);
1675             c.drawBitmap(thumbnailHeader, 0, 0, null);
1676             drawSurface.unlockCanvasAndPost(c);
1677             drawSurface.release();
1678 
1679             // Get the thumbnail animation
1680             Animation anim;
1681             if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1682                 // If this is a multi-window scenario, we use the windows frame as
1683                 // destination of the thumbnail header animation. If this is a full screen
1684                 // window scenario, we use the whole display as the target.
1685                 WindowState win = appToken.findMainWindow();
1686                 Rect appRect = win != null ? win.getContentFrameLw() :
1687                         new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1688                 Rect insets = win != null ? win.mContentInsets : null;
1689                 // For the new aspect-scaled transition, we want it to always show
1690                 // above the animating opening/closing window, and we want to
1691                 // synchronize its thumbnail surface with the surface for the
1692                 // open/close animation (only on the way down)
1693                 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
1694                         insets, thumbnailHeader, taskId, mService.mCurConfiguration.uiMode,
1695                         mService.mCurConfiguration.orientation);
1696                 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1697                 openingAppAnimator.deferThumbnailDestruction =
1698                         !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1699             } else {
1700                 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1701                         displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1702             }
1703             anim.restrictDuration(MAX_ANIMATION_DURATION);
1704             anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1705 
1706             openingAppAnimator.thumbnail = surfaceControl;
1707             openingAppAnimator.thumbnailLayer = openingLayer;
1708             openingAppAnimator.thumbnailAnimation = anim;
1709             mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
1710         } catch (Surface.OutOfResourcesException e) {
1711             Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
1712                     + dirty.width() + " h=" + dirty.height(), e);
1713             openingAppAnimator.clearThumbnail();
1714         }
1715     }
1716 
copyAnimToLayoutParamsLocked()1717     boolean copyAnimToLayoutParamsLocked() {
1718         boolean doRequest = false;
1719 
1720         final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1721         if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1722             mUpdateRotation = true;
1723             doRequest = true;
1724         }
1725         if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1726             mWallpaperMayChange = true;
1727             doRequest = true;
1728         }
1729         if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1730             mWallpaperForceHidingChanged = true;
1731             doRequest = true;
1732         }
1733         if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1734             mOrientationChangeComplete = false;
1735         } else {
1736             mOrientationChangeComplete = true;
1737             mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1738             if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1739                 doRequest = true;
1740             }
1741         }
1742         if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1743             mService.mTurnOnScreen = true;
1744         }
1745         if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1746             mWallpaperActionPending = true;
1747         }
1748 
1749         return doRequest;
1750     }
1751 
requestTraversal()1752     void requestTraversal() {
1753         if (!mTraversalScheduled) {
1754             mTraversalScheduled = true;
1755             mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1756         }
1757     }
1758 
1759     /**
1760      * Puts the {@param surface} into a pending list to be destroyed after the current transaction
1761      * has been committed.
1762      */
destroyAfterTransaction(SurfaceControl surface)1763     void destroyAfterTransaction(SurfaceControl surface) {
1764         mPendingDestroyingSurfaces.add(surface);
1765     }
1766 
1767     /**
1768      * Destroys any surfaces that have been put into the pending list with
1769      * {@link #destroyAfterTransaction}.
1770      */
destroyPendingSurfaces()1771     void destroyPendingSurfaces() {
1772         for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
1773             mPendingDestroyingSurfaces.get(i).destroy();
1774         }
1775         mPendingDestroyingSurfaces.clear();
1776     }
1777 
dump(PrintWriter pw, String prefix)1778     public void dump(PrintWriter pw, String prefix) {
1779         pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1780         pw.print(prefix); pw.print("mHoldScreenWindow="); pw.println(mHoldScreenWindow);
1781         pw.print(prefix); pw.print("mObsuringWindow="); pw.println(mObsuringWindow);
1782     }
1783 }
1784