Home | History | Annotate | Download | only in wm
      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 
    155     public WindowSurfacePlacer(WindowManagerService service) {
    156         mService = service;
    157         mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
    158     }
    159 
    160     /**
    161      * See {@link WindowManagerService#deferSurfaceLayout()}
    162      */
    163     void deferLayout() {
    164         mDeferDepth++;
    165     }
    166 
    167     /**
    168      * See {@link WindowManagerService#continueSurfaceLayout()}
    169      */
    170     void continueLayout() {
    171         mDeferDepth--;
    172         if (mDeferDepth <= 0) {
    173             performSurfacePlacement();
    174         }
    175     }
    176 
    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 
    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 
    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."
    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 
    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 
    890     boolean isInLayout() {
    891         return mInLayout;
    892     }
    893 
    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      */
   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 
   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 
   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 
   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 
   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      */
   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 
   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 
   1611     private static int toBrightnessOverride(float value) {
   1612         return (int)(value * PowerManager.BRIGHTNESS_ON);
   1613     }
   1614 
   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 
   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 
   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 
   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      */
   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      */
   1771     void destroyPendingSurfaces() {
   1772         for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
   1773             mPendingDestroyingSurfaces.get(i).destroy();
   1774         }
   1775         mPendingDestroyingSurfaces.clear();
   1776     }
   1777 
   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