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