package com.android.server.wm;

import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE;
import static android.app.ActivityManagerInternal.APP_TRANSITION_STARTING_WINDOW;
import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Debug;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.Slog;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
import android.view.WindowManager.LayoutParams;
import android.view.animation.Animation;

import com.android.server.wm.WindowManagerService.H;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Positions windows and their surfaces.
 *
 * It sets positions of windows by calculating their frames and then applies this by positioning
 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
 */
class WindowSurfacePlacer {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
    private final WindowManagerService mService;
    private final WallpaperController mWallpaperControllerLocked;

    private boolean mInLayout = false;

    /** Only do a maximum of 6 repeated layouts. After that quit */
    private int mLayoutRepeatCount;

    static final int SET_UPDATE_ROTATION                = 1 << 0;
    static final int SET_WALLPAPER_MAY_CHANGE           = 1 << 1;
    static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
    static final int SET_ORIENTATION_CHANGE_COMPLETE    = 1 << 3;
    static final int SET_TURN_ON_SCREEN                 = 1 << 4;
    static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 5;

    boolean mWallpaperMayChange = false;
    boolean mOrientationChangeComplete = true;
    boolean mWallpaperActionPending = false;

    private boolean mWallpaperForceHidingChanged = false;
    private Object mLastWindowFreezeSource = null;
    private Session mHoldScreen = null;
    private boolean mObscured = false;
    private boolean mSyswin = false;
    private float mScreenBrightness = -1;
    private float mButtonBrightness = -1;
    private long mUserActivityTimeout = -1;
    private boolean mUpdateRotation = false;
    private final Rect mTmpStartRect = new Rect();
    private final Rect mTmpContentRect = new Rect();

    // Set to true when the display contains content to show the user.
    // When false, the display manager may choose to mirror or blank the display.
    private boolean mDisplayHasContent = false;

    // Only set while traversing the default display based on its content.
    // Affects the behavior of mirroring on secondary displays.
    private boolean mObscureApplicationContentOnSecondaryDisplays = false;

    private float mPreferredRefreshRate = 0;

    private int mPreferredModeId = 0;

    private boolean mTraversalScheduled;
    private int mDeferDepth = 0;

    private boolean mSustainedPerformanceModeEnabled = false;
    private boolean mSustainedPerformanceModeCurrent = false;

    // Following variables are for debugging screen wakelock only.
    // Last window that requires screen wakelock
    WindowState mHoldScreenWindow = null;
    // Last window that obscures all windows below
    WindowState mObsuringWindow = null;

    private static final class LayerAndToken {
        public int layer;
        public AppWindowToken token;
    }
    private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();

    private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();

    public WindowSurfacePlacer(WindowManagerService service) {
        mService = service;
        mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
    }

    /**
     * See {@link WindowManagerService#deferSurfaceLayout()}
     */
    void deferLayout() {
        mDeferDepth++;
    }

    /**
     * See {@link WindowManagerService#continueSurfaceLayout()}
     */
    void continueLayout() {
        mDeferDepth--;
        if (mDeferDepth <= 0) {
            performSurfacePlacement();
        }
    }

    final void performSurfacePlacement() {
        if (mDeferDepth > 0) {
            return;
        }
        int loopCount = 6;
        do {
            mTraversalScheduled = false;
            performSurfacePlacementLoop();
            mService.mH.removeMessages(DO_TRAVERSAL);
            loopCount--;
        } while (mTraversalScheduled && loopCount > 0);
        mWallpaperActionPending = false;
    }

    private void performSurfacePlacementLoop() {
        if (mInLayout) {
            if (DEBUG) {
                throw new RuntimeException("Recursive call!");
            }
            Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
                    + Debug.getCallers(3));
            return;
        }

        if (mService.mWaitingForConfig) {
            // Our configuration has changed (most likely rotation), but we
            // don't yet have the complete configuration to report to
            // applications.  Don't do any window layout until we have it.
            return;
        }

        if (!mService.mDisplayReady) {
            // Not yet initialized, nothing to do.
            return;
        }

        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
        mInLayout = true;

        boolean recoveringMemory = false;
        if (!mService.mForceRemoves.isEmpty()) {
            recoveringMemory = true;
            // Wait a little bit for things to settle down, and off we go.
            while (!mService.mForceRemoves.isEmpty()) {
                WindowState ws = mService.mForceRemoves.remove(0);
                Slog.i(TAG, "Force removing: " + ws);
                mService.removeWindowInnerLocked(ws);
            }
            Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
            Object tmp = new Object();
            synchronized (tmp) {
                try {
                    tmp.wait(250);
                } catch (InterruptedException e) {
                }
            }
        }

        try {
            performSurfacePlacementInner(recoveringMemory);

            mInLayout = false;

            if (mService.needsLayout()) {
                if (++mLayoutRepeatCount < 6) {
                    requestTraversal();
                } else {
                    Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
                    mLayoutRepeatCount = 0;
                }
            } else {
                mLayoutRepeatCount = 0;
            }

            if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
                mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
                mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
            }
        } catch (RuntimeException e) {
            mInLayout = false;
            Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
        }

        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
    }

    void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
        if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
            Slog.v(TAG, "Layouts looping: " + msg +
                    ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
        }
    }

    // "Something has changed!  Let's make it correct now."
    private void performSurfacePlacementInner(boolean recoveringMemory) {
        if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
                + Debug.getCallers(3));

        int i;
        boolean updateInputWindowsNeeded = false;

        if (mService.mFocusMayChange) {
            mService.mFocusMayChange = false;
            updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
                    UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
        }

        // Initialize state of exiting tokens.
        final int numDisplays = mService.mDisplayContents.size();
        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
            final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
            for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
                displayContent.mExitingTokens.get(i).hasVisible = false;
            }
        }

        for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
            // Initialize state of exiting applications.
            final AppTokenList exitingAppTokens =
                    mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
            for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
                exitingAppTokens.get(tokenNdx).hasVisible = false;
            }
        }

        mHoldScreen = null;
        mHoldScreenWindow = null;
        mObsuringWindow = null;
        mScreenBrightness = -1;
        mButtonBrightness = -1;
        mUserActivityTimeout = -1;
        mObscureApplicationContentOnSecondaryDisplays = false;
        mSustainedPerformanceModeCurrent = false;
        mService.mTransactionSequence++;

        final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
        final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
        final int defaultDw = defaultInfo.logicalWidth;
        final int defaultDh = defaultInfo.logicalHeight;

        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
        SurfaceControl.openTransaction();
        try {
            applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
        } catch (RuntimeException e) {
            Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
        } finally {
            SurfaceControl.closeTransaction();
            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                    "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
        }

        final WindowList defaultWindows = defaultDisplay.getWindowList();

        // If we are ready to perform an app transition, check through
        // all of the app tokens to be shown and see if they are ready
        // to go.
        if (mService.mAppTransition.isReady()) {
            defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
            if (DEBUG_LAYOUT_REPEATS)
                debugLayoutRepeats("after handleAppTransitionReadyLocked",
                        defaultDisplay.pendingLayoutChanges);
        }

        if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
            // We have finished the animation of an app transition.  To do
            // this, we have delayed a lot of operations like showing and
            // hiding apps, moving apps in Z-order, etc.  The app token list
            // reflects the correct Z-order, but the window list may now
            // be out of sync with it.  So here we will just rebuild the
            // entire app window list.  Fun!
            defaultDisplay.pendingLayoutChanges |=
                    mService.handleAnimatingStoppedAndTransitionLocked();
            if (DEBUG_LAYOUT_REPEATS)
                debugLayoutRepeats("after handleAnimStopAndXitionLock",
                        defaultDisplay.pendingLayoutChanges);
        }

        if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
                && !mService.mAppTransition.isReady()) {
            // At this point, there was a window with a wallpaper that
            // was force hiding other windows behind it, but now it
            // is going away.  This may be simple -- just animate
            // away the wallpaper and its window -- or it may be
            // hard -- the wallpaper now needs to be shown behind
            // something that was hidden.
            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
            if (DEBUG_LAYOUT_REPEATS)
                debugLayoutRepeats("after animateAwayWallpaperLocked",
                        defaultDisplay.pendingLayoutChanges);
        }
        mWallpaperForceHidingChanged = false;

        if (mWallpaperMayChange) {
            if (DEBUG_WALLPAPER_LIGHT)
                Slog.v(TAG, "Wallpaper may change!  Adjusting");
            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
                    defaultDisplay.pendingLayoutChanges);
        }

        if (mService.mFocusMayChange) {
            mService.mFocusMayChange = false;
            if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                    false /*updateInputWindows*/)) {
                updateInputWindowsNeeded = true;
                defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
            }
        }

        if (mService.needsLayout()) {
            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
                    defaultDisplay.pendingLayoutChanges);
        }

        for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
            WindowState win = mService.mResizingWindows.get(i);
            if (win.mAppFreezing) {
                // Don't remove this window until rotation has completed.
                continue;
            }
            // Discard the saved surface if window size is changed, it can't be reused.
            if (win.mAppToken != null) {
                win.mAppToken.destroySavedSurfaces();
            }
            win.reportResized();
            mService.mResizingWindows.remove(i);
        }

        if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
                "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
        if (mOrientationChangeComplete) {
            if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
                mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
                mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
                mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
            }
            mService.stopFreezingDisplayLocked();
        }

        // Destroy the surface of any windows that are no longer visible.
        boolean wallpaperDestroyed = false;
        i = mService.mDestroySurface.size();
        if (i > 0) {
            do {
                i--;
                WindowState win = mService.mDestroySurface.get(i);
                win.mDestroying = false;
                if (mService.mInputMethodWindow == win) {
                    mService.mInputMethodWindow = null;
                }
                if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
                    wallpaperDestroyed = true;
                }
                win.destroyOrSaveSurface();
            } while (i > 0);
            mService.mDestroySurface.clear();
        }

        // Time to remove any exiting tokens?
        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
            final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
            ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
            for (i = exitingTokens.size() - 1; i >= 0; i--) {
                WindowToken token = exitingTokens.get(i);
                if (!token.hasVisible) {
                    exitingTokens.remove(i);
                    if (token.windowType == TYPE_WALLPAPER) {
                        mWallpaperControllerLocked.removeWallpaperToken(token);
                    }
                }
            }
        }

        // Time to remove any exiting applications?
        for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
            // Initialize state of exiting applications.
            final AppTokenList exitingAppTokens =
                    mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
            for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
                AppWindowToken token = exitingAppTokens.get(i);
                if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
                        (!token.mIsExiting || token.allAppWindows.isEmpty())) {
                    // Make sure there is no animation running on this token,
                    // so any windows associated with it will be removed as
                    // soon as their animations are complete
                    token.mAppAnimator.clearAnimation();
                    token.mAppAnimator.animating = false;
                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                            "performLayout: App token exiting now removed" + token);
                    token.removeAppFromTaskLocked();
                }
            }
        }

        if (wallpaperDestroyed) {
            defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
            defaultDisplay.layoutNeeded = true;
        }

        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
            final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
            if (displayContent.pendingLayoutChanges != 0) {
                displayContent.layoutNeeded = true;
            }
        }

        // Finally update all input windows now that the window changes have stabilized.
        mService.mInputMonitor.updateInputWindowsLw(true /*force*/);

        mService.setHoldScreenLocked(mHoldScreen);
        if (!mService.mDisplayFrozen) {
            if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
                mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
            } else {
                mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
                        toBrightnessOverride(mScreenBrightness));
            }
            if (mButtonBrightness < 0
                    || mButtonBrightness > 1.0f) {
                mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
            } else {
                mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
                        toBrightnessOverride(mButtonBrightness));
            }
            mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
                    mUserActivityTimeout);
        }

        if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
            mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
            mService.mPowerManagerInternal.powerHint(
                    mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
                    (mSustainedPerformanceModeEnabled ? 1 : 0));
        }

        if (mService.mTurnOnScreen) {
            if (mService.mAllowTheaterModeWakeFromLayout
                    || Settings.Global.getInt(mService.mContext.getContentResolver(),
                        Settings.Global.THEATER_MODE_ON, 0) == 0) {
                if (DEBUG_VISIBILITY || DEBUG_POWER) {
                    Slog.v(TAG, "Turning screen on after layout!");
                }
                mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
                        "android.server.wm:TURN_ON");
            }
            mService.mTurnOnScreen = false;
        }

        if (mUpdateRotation) {
            if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
            if (mService.updateRotationUncheckedLocked(false)) {
                mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
            } else {
                mUpdateRotation = false;
            }
        }

        if (mService.mWaitingForDrawnCallback != null ||
                (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
                        !mUpdateRotation)) {
            mService.checkDrawnWindowsLocked();
        }

        final int N = mService.mPendingRemove.size();
        if (N > 0) {
            if (mService.mPendingRemoveTmp.length < N) {
                mService.mPendingRemoveTmp = new WindowState[N+10];
            }
            mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
            mService.mPendingRemove.clear();
            DisplayContentList displayList = new DisplayContentList();
            for (i = 0; i < N; i++) {
                WindowState w = mService.mPendingRemoveTmp[i];
                mService.removeWindowInnerLocked(w);
                final DisplayContent displayContent = w.getDisplayContent();
                if (displayContent != null && !displayList.contains(displayContent)) {
                    displayList.add(displayContent);
                }
            }

            for (DisplayContent displayContent : displayList) {
                mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
                displayContent.layoutNeeded = true;
            }
        }

        // Remove all deferred displays stacks, tasks, and activities.
        for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
            mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
        }

        if (updateInputWindowsNeeded) {
            mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
        }
        mService.setFocusTaskRegionLocked();

        // Check to see if we are now in a state where the screen should
        // be enabled, because the window obscured flags have changed.
        mService.enableScreenIfNeededLocked();

        mService.scheduleAnimationLocked();
        mService.mWindowPlacerLocked.destroyPendingSurfaces();

        if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
                "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
    }

    private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
            int defaultDw, int defaultDh) {
        if (mService.mWatermark != null) {
            mService.mWatermark.positionSurface(defaultDw, defaultDh);
        }
        if (mService.mStrictModeFlash != null) {
            mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
        }
        if (mService.mCircularDisplayMask != null) {
            mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
                    mService.mRotation);
        }
        if (mService.mEmulatorDisplayOverlay != null) {
            mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
                    mService.mRotation);
        }

        boolean focusDisplayed = false;

        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
            final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
            boolean updateAllDrawn = false;
            WindowList windows = displayContent.getWindowList();
            DisplayInfo displayInfo = displayContent.getDisplayInfo();
            final int displayId = displayContent.getDisplayId();
            final int dw = displayInfo.logicalWidth;
            final int dh = displayInfo.logicalHeight;
            final int innerDw = displayInfo.appWidth;
            final int innerDh = displayInfo.appHeight;
            final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);

            // Reset for each display.
            mDisplayHasContent = false;
            mPreferredRefreshRate = 0;
            mPreferredModeId = 0;

            int repeats = 0;
            do {
                repeats++;
                if (repeats > 6) {
                    Slog.w(TAG, "Animation repeat aborted after too many iterations");
                    displayContent.layoutNeeded = false;
                    break;
                }

                if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
                        "On entry to LockedInner", displayContent.pendingLayoutChanges);

                if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
                        mWallpaperControllerLocked.adjustWallpaperWindows()) {
                    mService.mLayersController.assignLayersLocked(windows);
                    displayContent.layoutNeeded = true;
                }

                if (isDefaultDisplay
                        && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
                    if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
                    if (mService.updateOrientationFromAppTokensLocked(true)) {
                        displayContent.layoutNeeded = true;
                        mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
                    }
                }

                if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
                    displayContent.layoutNeeded = true;
                }

                // FIRST LOOP: Perform a layout, if needed.
                if (repeats < LAYOUT_REPEAT_THRESHOLD) {
                    performLayoutLockedInner(displayContent, repeats == 1,
                            false /* updateInputWindows */);
                } else {
                    Slog.w(TAG, "Layout repeat skipped after too many iterations");
                }

                // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
                // it is animating.
                displayContent.pendingLayoutChanges = 0;

                if (isDefaultDisplay) {
                    mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
                    for (int i = windows.size() - 1; i >= 0; i--) {
                        WindowState w = windows.get(i);
                        if (w.mHasSurface) {
                            mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
                                    w.mAttachedWindow);
                        }
                    }
                    displayContent.pendingLayoutChanges |=
                            mService.mPolicy.finishPostLayoutPolicyLw();
                    if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
                            displayContent.pendingLayoutChanges);
                }
            } while (displayContent.pendingLayoutChanges != 0);

            mObscured = false;
            mSyswin = false;
            displayContent.resetDimming();

            // Only used if default window
            final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();

            for (int i = windows.size() - 1; i >= 0; i--) {
                WindowState w = windows.get(i);
                final Task task = w.getTask();
                final boolean obscuredChanged = w.mObscured != mObscured;

                // Update effect.
                w.mObscured = mObscured;
                if (!mObscured) {
                    handleNotObscuredLocked(w, displayInfo);
                }

                w.applyDimLayerIfNeeded();

                if (isDefaultDisplay && obscuredChanged
                        && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
                    // This is the wallpaper target and its obscured state
                    // changed... make sure the current wallaper's visibility
                    // has been updated accordingly.
                    mWallpaperControllerLocked.updateWallpaperVisibility();
                }

                final WindowStateAnimator winAnimator = w.mWinAnimator;

                // If the window has moved due to its containing content frame changing, then
                // notify the listeners and optionally animate it. Simply checking a change of
                // position is not enough, because being move due to dock divider is not a trigger
                // for animation.
                if (w.hasMoved()) {
                    // Frame has moved, containing content frame has also moved, and we're not
                    // currently animating... let's do something.
                    final int left = w.mFrame.left;
                    final int top = w.mFrame.top;
                    final boolean adjustedForMinimizedDockOrIme = task != null
                                && (task.mStack.isAdjustedForMinimizedDockedStack()
                                    || task.mStack.isAdjustedForIme());
                    if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
                            && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
                            && (task == null || w.getTask().mStack.hasMovementAnimations())
                            && !w.mWinAnimator.mLastHidden) {
                        winAnimator.setMoveAnimation(left, top);
                    }

                    //TODO (multidisplay): Accessibility supported only for the default display.
                    if (mService.mAccessibilityController != null
                            && displayId == Display.DEFAULT_DISPLAY) {
                        mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
                    }

                    try {
                        w.mClient.moved(left, top);
                    } catch (RemoteException e) {
                    }
                    w.mMovedByResize = false;
                }

                //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
                w.mContentChanged = false;

                // Moved from updateWindowsAndWallpaperLocked().
                if (w.mHasSurface) {
                    // If we have recently synchronized a previous transaction for this
                    // window ensure we don't push through an unsynchronized one now.
                    winAnimator.deferToPendingTransaction();

                    // Take care of the window being ready to display.
                    final boolean committed = winAnimator.commitFinishDrawingLocked();
                    if (isDefaultDisplay && committed) {
                        if (w.mAttrs.type == TYPE_DREAM) {
                            // HACK: When a dream is shown, it may at that
                            // point hide the lock screen.  So we need to
                            // redo the layout to let the phone window manager
                            // make this happen.
                            displayContent.pendingLayoutChanges |=
                                    FINISH_LAYOUT_REDO_LAYOUT;
                            if (DEBUG_LAYOUT_REPEATS) {
                                debugLayoutRepeats("dream and commitFinishDrawingLocked true",
                                        displayContent.pendingLayoutChanges);
                            }
                        }
                        if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
                            if (DEBUG_WALLPAPER_LIGHT)
                                Slog.v(TAG, "First draw done in potential wallpaper target " + w);
                            mWallpaperMayChange = true;
                            displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                            if (DEBUG_LAYOUT_REPEATS) {
                                debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
                                        displayContent.pendingLayoutChanges);
                            }
                        }
                    }
                    if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
                        // Updates the shown frame before we set up the surface. This is needed
                        // because the resizing could change the top-left position (in addition to
                        // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
                        // position the surface.
                        //
                        // If an animation is being started, we can't call this method because the
                        // animation hasn't processed its initial transformation yet, but in general
                        // we do want to update the position if the window is animating.
                        winAnimator.computeShownFrameLocked();
                    }
                    winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
                }

                final AppWindowToken atoken = w.mAppToken;
                if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
                    Slog.d(TAG, "updateWindows: starting " + w
                            + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
                            + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
                }
                if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
                        || atoken.mAppAnimator.freezingScreen)) {
                    if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
                        atoken.lastTransactionSequence = mService.mTransactionSequence;
                        atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
                        atoken.numInterestingWindowsExcludingSaved = 0;
                        atoken.numDrawnWindowsExclusingSaved = 0;
                        atoken.startingDisplayed = false;
                    }
                    if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
                        if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
                            Slog.v(TAG, "Eval win " + w + ": isDrawn="
                                    + w.isDrawnLw()
                                    + ", isAnimationSet=" + winAnimator.isAnimationSet());
                            if (!w.isDrawnLw()) {
                                Slog.v(TAG, "Not displayed: s="
                                        + winAnimator.mSurfaceController
                                        + " pv=" + w.mPolicyVisibility
                                        + " mDrawState=" + winAnimator.drawStateToString()
                                        + " ah=" + w.mAttachedHidden
                                        + " th=" + atoken.hiddenRequested
                                        + " a=" + winAnimator.mAnimating);
                            }
                        }
                        if (w != atoken.startingWindow) {
                            if (w.isInteresting()) {
                                atoken.numInterestingWindows++;
                                if (w.isDrawnLw()) {
                                    atoken.numDrawnWindows++;
                                    if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
                                        Slog.v(TAG, "tokenMayBeDrawn: " + atoken
                                                + " w=" + w + " numInteresting="
                                                + atoken.numInterestingWindows
                                                + " freezingScreen="
                                                + atoken.mAppAnimator.freezingScreen
                                                + " mAppFreezing=" + w.mAppFreezing);
                                    updateAllDrawn = true;
                                }
                            }
                        } else if (w.isDrawnLw()) {
                            mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
                            atoken.startingDisplayed = true;
                        }
                    }
                    if (!atoken.allDrawnExcludingSaved
                            && w.mightAffectAllDrawn(true /* visibleOnly */)) {
                        if (w != atoken.startingWindow && w.isInteresting()) {
                            atoken.numInterestingWindowsExcludingSaved++;
                            if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
                                atoken.numDrawnWindowsExclusingSaved++;
                                if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
                                    Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
                                            + " w=" + w + " numInteresting="
                                            + atoken.numInterestingWindowsExcludingSaved
                                            + " freezingScreen="
                                            + atoken.mAppAnimator.freezingScreen
                                            + " mAppFreezing=" + w.mAppFreezing);
                                updateAllDrawn = true;
                            }
                        }
                    }
                }

                if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
                        && w.isDisplayedLw()) {
                    focusDisplayed = true;
                }

                mService.updateResizingWindows(w);
            }

            mService.mDisplayManagerInternal.setDisplayProperties(displayId,
                    mDisplayHasContent,
                    mPreferredRefreshRate,
                    mPreferredModeId,
                    true /* inTraversal, must call performTraversalInTrans... below */);

            mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();

            if (updateAllDrawn) {
                updateAllDrawnLocked(displayContent);
            }
        }

        if (focusDisplayed) {
            mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
        }

        // Give the display manager a chance to adjust properties
        // like display rotation if it needs to.
        mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
    }

    boolean isInLayout() {
        return mInLayout;
    }

    final void performLayoutLockedInner(final DisplayContent displayContent,
            boolean initial, boolean updateInputWindows) {
        if (!displayContent.layoutNeeded) {
            return;
        }
        displayContent.layoutNeeded = false;
        WindowList windows = displayContent.getWindowList();
        boolean isDefaultDisplay = displayContent.isDefaultDisplay;

        DisplayInfo displayInfo = displayContent.getDisplayInfo();
        final int dw = displayInfo.logicalWidth;
        final int dh = displayInfo.logicalHeight;

        if (mService.mInputConsumer != null) {
            mService.mInputConsumer.layout(dw, dh);
        }

        if (mService.mWallpaperInputConsumer != null) {
            mService.mWallpaperInputConsumer.layout(dw, dh);
        }

        final int N = windows.size();
        int i;

        if (DEBUG_LAYOUT) {
            Slog.v(TAG, "-------------------------------------");
            Slog.v(TAG, "performLayout: needed="
                    + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
        }

        mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
                mService.mCurConfiguration.uiMode);
        if (isDefaultDisplay) {
            // Not needed on non-default displays.
            mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
            mService.mScreenRect.set(0, 0, dw, dh);
        }

        mService.mPolicy.getContentRectLw(mTmpContentRect);
        displayContent.resize(mTmpContentRect);

        int seq = mService.mLayoutSeq+1;
        if (seq < 0) seq = 0;
        mService.mLayoutSeq = seq;

        boolean behindDream = false;

        // First perform layout of any root windows (not attached
        // to another window).
        int topAttached = -1;
        for (i = N-1; i >= 0; i--) {
            final WindowState win = windows.get(i);

            // Don't do layout of a window if it is not visible, or
            // soon won't be visible, to avoid wasting time and funky
            // changes while a window is animating away.
            final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
                    || win.isGoneForLayoutLw();

            if (DEBUG_LAYOUT && !win.mLayoutAttached) {
                Slog.v(TAG, "1ST PASS " + win
                        + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
                        + " mLayoutAttached=" + win.mLayoutAttached
                        + " screen changed=" + win.isConfigChanged());
                final AppWindowToken atoken = win.mAppToken;
                if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
                        + win.mViewVisibility + " mRelayoutCalled="
                        + win.mRelayoutCalled + " hidden="
                        + win.mRootToken.hidden + " hiddenRequested="
                        + (atoken != null && atoken.hiddenRequested)
                        + " mAttachedHidden=" + win.mAttachedHidden);
                else Slog.v(TAG, "  VIS: mViewVisibility="
                        + win.mViewVisibility + " mRelayoutCalled="
                        + win.mRelayoutCalled + " hidden="
                        + win.mRootToken.hidden + " hiddenRequested="
                        + (atoken != null && atoken.hiddenRequested)
                        + " mAttachedHidden=" + win.mAttachedHidden);
            }

            // If this view is GONE, then skip it -- keep the current
            // frame, and let the caller know so they can ignore it
            // if they want.  (We do the normal layout for INVISIBLE
            // windows, since that means "perform layout as normal,
            // just don't display").
            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
                    || ((win.isConfigChanged() || win.setReportResizeHints())
                            && !win.isGoneForLayoutLw() &&
                            ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
                            (win.mHasSurface && win.mAppToken != null &&
                            win.mAppToken.layoutConfigChanges)))) {
                if (!win.mLayoutAttached) {
                    if (initial) {
                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
                        win.mContentChanged = false;
                    }
                    if (win.mAttrs.type == TYPE_DREAM) {
                        // Don't layout windows behind a dream, so that if it
                        // does stuff like hide the status bar we won't get a
                        // bad transition when it goes away.
                        behindDream = true;
                    }
                    win.mLayoutNeeded = false;
                    win.prelayout();
                    mService.mPolicy.layoutWindowLw(win, null);
                    win.mLayoutSeq = seq;

                    // Window frames may have changed. Update dim layer with the new bounds.
                    final Task task = win.getTask();
                    if (task != null) {
                        displayContent.mDimLayerController.updateDimLayer(task);
                    }

                    if (DEBUG_LAYOUT) Slog.v(TAG,
                            "  LAYOUT: mFrame="
                            + win.mFrame + " mContainingFrame="
                            + win.mContainingFrame + " mDisplayFrame="
                            + win.mDisplayFrame);
                } else {
                    if (topAttached < 0) topAttached = i;
                }
            }
        }

        boolean attachedBehindDream = false;

        // Now perform layout of attached windows, which usually
        // depend on the position of the window they are attached to.
        // XXX does not deal with windows that are attached to windows
        // that are themselves attached.
        for (i = topAttached; i >= 0; i--) {
            final WindowState win = windows.get(i);

            if (win.mLayoutAttached) {
                if (DEBUG_LAYOUT) Slog.v(TAG,
                        "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
                        + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
                // If this view is GONE, then skip it -- keep the current
                // frame, and let the caller know so they can ignore it
                // if they want.  (We do the normal layout for INVISIBLE
                // windows, since that means "perform layout as normal,
                // just don't display").
                if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
                    continue;
                }
                if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
                        || !win.mHaveFrame || win.mLayoutNeeded) {
                    if (initial) {
                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
                        win.mContentChanged = false;
                    }
                    win.mLayoutNeeded = false;
                    win.prelayout();
                    mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
                    win.mLayoutSeq = seq;
                    if (DEBUG_LAYOUT) Slog.v(TAG,
                            "  LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
                            + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
                }
            } else if (win.mAttrs.type == TYPE_DREAM) {
                // Don't layout windows behind a dream, so that if it
                // does stuff like hide the status bar we won't get a
                // bad transition when it goes away.
                attachedBehindDream = behindDream;
            }
        }

        // Window frames may have changed. Tell the input dispatcher about it.
        mService.mInputMonitor.setUpdateInputWindowsNeededLw();
        if (updateInputWindows) {
            mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
        }

        mService.mPolicy.finishLayoutLw();
        mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
    }

    /**
     * @param windows List of windows on default display.
     * @return bitmap indicating if another pass through layout must be made.
     */
    private int handleAppTransitionReadyLocked(WindowList windows) {
        int appsCount = mService.mOpeningApps.size();
        if (!transitionGoodToGo(appsCount)) {
            return 0;
        }
        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");

        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
        int transit = mService.mAppTransition.getAppTransition();
        if (mService.mSkipAppTransitionAnimation) {
            transit = AppTransition.TRANSIT_UNSET;
        }
        mService.mSkipAppTransitionAnimation = false;
        mService.mNoAnimationNotifyOnTransitionFinished.clear();

        mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);

        mService.rebuildAppWindowListLocked();

        mWallpaperMayChange = false;

        // The top-most window will supply the layout params,
        // and we will determine it below.
        LayoutParams animLp = null;
        int bestAnimLayer = -1;
        boolean fullscreenAnim = false;
        boolean voiceInteraction = false;

        final WindowState lowerWallpaperTarget =
                mWallpaperControllerLocked.getLowerWallpaperTarget();
        final WindowState upperWallpaperTarget =
                mWallpaperControllerLocked.getUpperWallpaperTarget();

        boolean openingAppHasWallpaper = false;
        boolean closingAppHasWallpaper = false;
        final AppWindowToken lowerWallpaperAppToken;
        final AppWindowToken upperWallpaperAppToken;
        if (lowerWallpaperTarget == null) {
            lowerWallpaperAppToken = upperWallpaperAppToken = null;
        } else {
            lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
            upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
        }

        int i;
        // Do a first pass through the tokens for two
        // things:
        // (1) Determine if both the closing and opening
        // app token sets are wallpaper targets, in which
        // case special animations are needed
        // (since the wallpaper needs to stay static
        // behind them).
        // (2) Find the layout params of the top-most
        // application window in the tokens, which is
        // what will control the animation theme.
        final int closingAppsCount = mService.mClosingApps.size();
        appsCount = closingAppsCount + mService.mOpeningApps.size();
        for (i = 0; i < appsCount; i++) {
            final AppWindowToken wtoken;
            if (i < closingAppsCount) {
                wtoken = mService.mClosingApps.valueAt(i);
                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
                    closingAppHasWallpaper = true;
                }
            } else {
                wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
                if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
                    openingAppHasWallpaper = true;
                }
            }

            voiceInteraction |= wtoken.voiceInteraction;

            if (wtoken.appFullscreen) {
                WindowState ws = wtoken.findMainWindow();
                if (ws != null) {
                    animLp = ws.mAttrs;
                    bestAnimLayer = ws.mLayer;
                    fullscreenAnim = true;
                }
            } else if (!fullscreenAnim) {
                WindowState ws = wtoken.findMainWindow();
                if (ws != null) {
                    if (ws.mLayer > bestAnimLayer) {
                        animLp = ws.mAttrs;
                        bestAnimLayer = ws.mLayer;
                    }
                }
            }
        }

        transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
                closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);

        // If all closing windows are obscured, then there is
        // no need to do an animation.  This is the case, for
        // example, when this transition is being done behind
        // the lock screen.
        if (!mService.mPolicy.allowAppAnimationsLw()) {
            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                    "Animations disallowed by keyguard or dream.");
            animLp = null;
        }

        processApplicationsAnimatingInPlace(transit);

        mTmpLayerAndToken.token = null;
        handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
        final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
        final int topClosingLayer = mTmpLayerAndToken.layer;

        final AppWindowToken topOpeningApp = handleOpeningApps(transit,
                animLp, voiceInteraction, topClosingLayer);

        final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
                topOpeningApp.mAppAnimator;
        final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
                topClosingApp.mAppAnimator;

        mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
                mService.mOpeningApps, mService.mClosingApps);
        mService.mAppTransition.postAnimationCallback();
        mService.mAppTransition.clear();

        mService.mOpeningApps.clear();
        mService.mClosingApps.clear();

        // This has changed the visibility of windows, so perform
        // a new layout to get them all up-to-date.
        mService.getDefaultDisplayContentLocked().layoutNeeded = true;

        // TODO(multidisplay): IMEs are only supported on the default display.
        if (windows == mService.getDefaultWindowListLocked()
                && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
            mService.mLayersController.assignLayersLocked(windows);
        }
        mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                true /*updateInputWindows*/);
        mService.mFocusMayChange = false;
        mService.notifyActivityDrawnForKeyguard();

        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);

        return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
    }

    private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
            boolean voiceInteraction, int topClosingLayer) {
        AppWindowToken topOpeningApp = null;
        final int appsCount = mService.mOpeningApps.size();
        for (int i = 0; i < appsCount; i++) {
            AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);

            if (!appAnimator.usingTransferredAnimation) {
                appAnimator.clearThumbnail();
                appAnimator.setNullAnimation();
            }
            wtoken.inPendingTransaction = false;

            if (!mService.setTokenVisibilityLocked(
                    wtoken, animLp, true, transit, false, voiceInteraction)){
                // This token isn't going to be animating. Add it to the list of tokens to
                // be notified of app transition complete since the notification will not be
                // sent be the app window animator.
                mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
            }
            wtoken.updateReportedVisibilityLocked();
            wtoken.waitingToShow = false;

            appAnimator.mAllAppWinAnimators.clear();
            final int windowsCount = wtoken.allAppWindows.size();
            for (int j = 0; j < windowsCount; j++) {
                appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
            }
            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                    ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
            SurfaceControl.openTransaction();
            try {
                mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
            } finally {
                SurfaceControl.closeTransaction();
                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                        "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
            }
            mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();

            int topOpeningLayer = 0;
            if (animLp != null) {
                int layer = -1;
                for (int j = 0; j < wtoken.allAppWindows.size(); j++) {
                    final WindowState win = wtoken.allAppWindows.get(j);
                    // Clearing the mAnimatingExit flag before entering animation. It will be set to true
                    // if app window is removed, or window relayout to invisible. We don't want to
                    // clear it out for windows that get replaced, because the animation depends on
                    // the flag to remove the replaced window.
                    //
                    // We also don't clear the mAnimatingExit flag for windows which have the
                    // mRemoveOnExit flag. This indicates an explicit remove request has been issued
                    // by the client. We should let animation proceed and not clear this flag or
                    // they won't eventually be removed by WindowStateAnimator#finishExit.
                    if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
                        win.mAnimatingExit = false;
                        // Clear mAnimating flag together with mAnimatingExit. When animation
                        // changes from exiting to entering, we need to clear this flag until the
                        // new animation gets applied, so that isAnimationStarting() becomes true
                        // until then.
                        // Otherwise applySurfaceChangesTransaction will faill to skip surface
                        // placement for this window during this period, one or more frame will
                        // show up with wrong position or scale.
                        win.mWinAnimator.mAnimating = false;
                    }
                    if (win.mWinAnimator.mAnimLayer > layer) {
                        layer = win.mWinAnimator.mAnimLayer;
                    }
                }
                if (topOpeningApp == null || layer > topOpeningLayer) {
                    topOpeningApp = wtoken;
                    topOpeningLayer = layer;
                }
            }
            if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
                createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
            }
        }
        return topOpeningApp;
    }

    private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
            LayerAndToken layerAndToken) {
        final int appsCount;
        appsCount = mService.mClosingApps.size();
        for (int i = 0; i < appsCount; i++) {
            AppWindowToken wtoken = mService.mClosingApps.valueAt(i);

            // If we still have some windows animating with saved surfaces that's
            // either invisible or already removed, mark them exiting so that they
            // are disposed of after the exit animation. These are not supposed to
            // be shown, or are delayed removal until app is actually drawn (in which
            // case the window will be removed after the animation).
            wtoken.markSavedSurfaceExiting();

            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
            appAnimator.clearThumbnail();
            appAnimator.setNullAnimation();
            wtoken.inPendingTransaction = false;
            mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
                    voiceInteraction);
            wtoken.updateReportedVisibilityLocked();
            // Force the allDrawn flag, because we want to start
            // this guy's animations regardless of whether it's
            // gotten drawn.
            wtoken.allDrawn = true;
            wtoken.deferClearAllDrawn = false;
            // Ensure that apps that are mid-starting are also scheduled to have their
            // starting windows removed after the animation is complete
            if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
                mService.scheduleRemoveStartingWindowLocked(wtoken);
            }
            mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();

            if (animLp != null) {
                int layer = -1;
                for (int j = 0; j < wtoken.windows.size(); j++) {
                    WindowState win = wtoken.windows.get(j);
                    if (win.mWinAnimator.mAnimLayer > layer) {
                        layer = win.mWinAnimator.mAnimLayer;
                    }
                }
                if (layerAndToken.token == null || layer > layerAndToken.layer) {
                    layerAndToken.token = wtoken;
                    layerAndToken.layer = layer;
                }
            }
            if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
                createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
            }
        }
    }

    private boolean transitionGoodToGo(int appsCount) {
        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                "Checking " + appsCount + " opening apps (frozen="
                        + mService.mDisplayFrozen + " timeout="
                        + mService.mAppTransition.isTimeout() + ")...");
        int reason = APP_TRANSITION_TIMEOUT;
        if (!mService.mAppTransition.isTimeout()) {
            for (int i = 0; i < appsCount; i++) {
                AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                        "Check opening app=" + wtoken + ": allDrawn="
                        + wtoken.allDrawn + " startingDisplayed="
                        + wtoken.startingDisplayed + " startingMoved="
                        + wtoken.startingMoved + " isRelaunching()="
                        + wtoken.isRelaunching());

                if (wtoken.isRelaunching()) {
                    return false;
                }

                final boolean drawnBeforeRestoring = wtoken.allDrawn;
                wtoken.restoreSavedSurfaces();

                if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
                    return false;
                }
                if (wtoken.allDrawn) {
                    reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
                            : APP_TRANSITION_SAVED_SURFACE;
                } else {
                    reason = APP_TRANSITION_STARTING_WINDOW;
                }
            }

            // We also need to wait for the specs to be fetched, if needed.
            if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
                return false;
            }

            // If the wallpaper is visible, we need to check it's ready too.
            boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
                    mWallpaperControllerLocked.wallpaperTransitionReady();
            if (wallpaperReady) {
                mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
                return true;
            }
            return false;
        }
        mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
        return true;
    }

    private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
            boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
            WindowState upperWallpaperTarget) {
        // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
        final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
        final WindowState oldWallpaper =
                mWallpaperControllerLocked.isWallpaperTargetAnimating()
                        ? null : wallpaperTarget;
        final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
        final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                "New wallpaper target=" + wallpaperTarget
                        + ", oldWallpaper=" + oldWallpaper
                        + ", lower target=" + lowerWallpaperTarget
                        + ", upper target=" + upperWallpaperTarget
                        + ", openingApps=" + openingApps
                        + ", closingApps=" + closingApps);
        mService.mAnimateWallpaperWithTarget = false;
        if (closingAppHasWallpaper && openingAppHasWallpaper) {
            if (DEBUG_APP_TRANSITIONS)
                Slog.v(TAG, "Wallpaper animation!");
            switch (transit) {
                case AppTransition.TRANSIT_ACTIVITY_OPEN:
                case AppTransition.TRANSIT_TASK_OPEN:
                case AppTransition.TRANSIT_TASK_TO_FRONT:
                    transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
                    break;
                case AppTransition.TRANSIT_ACTIVITY_CLOSE:
                case AppTransition.TRANSIT_TASK_CLOSE:
                case AppTransition.TRANSIT_TASK_TO_BACK:
                    transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
                    break;
            }
            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                    "New transit: " + AppTransition.appTransitionToString(transit));
        } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
                && !openingApps.contains(oldWallpaper.mAppToken)
                && closingApps.contains(oldWallpaper.mAppToken)) {
            // We are transitioning from an activity with a wallpaper to one without.
            transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                    "New transit away from wallpaper: "
                    + AppTransition.appTransitionToString(transit));
        } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
                openingApps.contains(wallpaperTarget.mAppToken)) {
            // We are transitioning from an activity without
            // a wallpaper to now showing the wallpaper
            transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                    "New transit into wallpaper: "
                    + AppTransition.appTransitionToString(transit));
        } else {
            mService.mAnimateWallpaperWithTarget = true;
        }
        return transit;
    }

    /**
     * @param w WindowState this method is applied to.
     * @param dispInfo info of the display that the window's obscuring state is checked against.
     */
    private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
        final LayoutParams attrs = w.mAttrs;
        final int attrFlags = attrs.flags;
        final boolean canBeSeen = w.isDisplayedLw();
        final int privateflags = attrs.privateFlags;

        if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
            // This window completely covers everything behind it,
            // so we want to leave all of them as undimmed (for
            // performance reasons).
            if (!mObscured) {
                mObsuringWindow = w;
            }

            mObscured = true;
        }

        if (w.mHasSurface) {
            if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
                mHoldScreen = w.mSession;
                mHoldScreenWindow = w;
            } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
                Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
                        + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
                        + Debug.getCallers(10));
            }
            if (!mSyswin && w.mAttrs.screenBrightness >= 0
                    && mScreenBrightness < 0) {
                mScreenBrightness = w.mAttrs.screenBrightness;
            }
            if (!mSyswin && w.mAttrs.buttonBrightness >= 0
                    && mButtonBrightness < 0) {
                mButtonBrightness = w.mAttrs.buttonBrightness;
            }
            if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
                    && mUserActivityTimeout < 0) {
                mUserActivityTimeout = w.mAttrs.userActivityTimeout;
            }

            final int type = attrs.type;
            if (canBeSeen
                    && (type == TYPE_SYSTEM_DIALOG
                     || type == TYPE_SYSTEM_ERROR
                     || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
                mSyswin = true;
            }

            if (canBeSeen) {
                // This function assumes that the contents of the default display are
                // processed first before secondary displays.
                final DisplayContent displayContent = w.getDisplayContent();
                if (displayContent != null && displayContent.isDefaultDisplay) {
                    // While a dream or keyguard is showing, obscure ordinary application
                    // content on secondary displays (by forcibly enabling mirroring unless
                    // there is other content we want to show) but still allow opaque
                    // keyguard dialogs to be shown.
                    if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                        mObscureApplicationContentOnSecondaryDisplays = true;
                    }
                    mDisplayHasContent = true;
                } else if (displayContent != null &&
                        (!mObscureApplicationContentOnSecondaryDisplays
                        || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
                    // Allow full screen keyguard presentation dialogs to be seen.
                    mDisplayHasContent = true;
                }
                if (mPreferredRefreshRate == 0
                        && w.mAttrs.preferredRefreshRate != 0) {
                    mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
                }
                if (mPreferredModeId == 0
                        && w.mAttrs.preferredDisplayModeId != 0) {
                    mPreferredModeId = w.mAttrs.preferredDisplayModeId;
                }
                if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
                    mSustainedPerformanceModeCurrent = true;
                }
            }
        }
    }

    private void updateAllDrawnLocked(DisplayContent displayContent) {
        // See if any windows have been drawn, so they (and others
        // associated with them) can now be shown.
        ArrayList<TaskStack> stacks = displayContent.getStacks();
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
                final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
                    final AppWindowToken wtoken = tokens.get(tokenNdx);
                    if (!wtoken.allDrawn) {
                        int numInteresting = wtoken.numInterestingWindows;
                        if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
                            if (DEBUG_VISIBILITY)
                                Slog.v(TAG, "allDrawn: " + wtoken
                                    + " interesting=" + numInteresting
                                    + " drawn=" + wtoken.numDrawnWindows);
                            wtoken.allDrawn = true;
                            // Force an additional layout pass where WindowStateAnimator#
                            // commitFinishDrawingLocked() will call performShowLocked().
                            displayContent.layoutNeeded = true;
                            mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
                                    wtoken.token).sendToTarget();
                        }
                    }
                    if (!wtoken.allDrawnExcludingSaved) {
                        int numInteresting = wtoken.numInterestingWindowsExcludingSaved;
                        if (numInteresting > 0
                                && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) {
                            if (DEBUG_VISIBILITY)
                                Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken
                                    + " interesting=" + numInteresting
                                    + " drawn=" + wtoken.numDrawnWindowsExclusingSaved);
                            wtoken.allDrawnExcludingSaved = true;
                            displayContent.layoutNeeded = true;
                            if (wtoken.isAnimatingInvisibleWithSavedSurface()
                                    && !mService.mFinishedEarlyAnim.contains(wtoken)) {
                                mService.mFinishedEarlyAnim.add(wtoken);
                            }
                        }
                    }
                }
            }
        }
    }

    private static int toBrightnessOverride(float value) {
        return (int)(value * PowerManager.BRIGHTNESS_ON);
    }

    private void processApplicationsAnimatingInPlace(int transit) {
        if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
            // Find the focused window
            final WindowState win = mService.findFocusedWindowLocked(
                    mService.getDefaultDisplayContentLocked());
            if (win != null) {
                final AppWindowToken wtoken = win.mAppToken;
                final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
                if (DEBUG_APP_TRANSITIONS)
                    Slog.v(TAG, "Now animating app in place " + wtoken);
                appAnimator.clearThumbnail();
                appAnimator.setNullAnimation();
                mService.updateTokenInPlaceLocked(wtoken, transit);
                wtoken.updateReportedVisibilityLocked();

                appAnimator.mAllAppWinAnimators.clear();
                final int N = wtoken.allAppWindows.size();
                for (int j = 0; j < N; j++) {
                    appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
                }
                mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
                mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
            }
        }
    }

    private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
            int openingLayer, int closingLayer) {
        AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
        if (openingAppAnimator == null || openingAppAnimator.animation == null) {
            return;
        }
        final int taskId = appToken.mTask.mTaskId;
        Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
        if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
            return;
        }
        // This thumbnail animation is very special, we need to have
        // an extra surface with the thumbnail included with the animation.
        Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
        try {
            // TODO(multi-display): support other displays
            final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
            final Display display = displayContent.getDisplay();
            final DisplayInfo displayInfo = displayContent.getDisplayInfo();

            // Create a new surface for the thumbnail
            SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
                    "thumbnail anim", dirty.width(), dirty.height(),
                    PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
            surfaceControl.setLayerStack(display.getLayerStack());
            if (SHOW_TRANSACTIONS) {
                Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
            }

            // Draw the thumbnail onto the surface
            Surface drawSurface = new Surface();
            drawSurface.copyFrom(surfaceControl);
            Canvas c = drawSurface.lockCanvas(dirty);
            c.drawBitmap(thumbnailHeader, 0, 0, null);
            drawSurface.unlockCanvasAndPost(c);
            drawSurface.release();

            // Get the thumbnail animation
            Animation anim;
            if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
                // If this is a multi-window scenario, we use the windows frame as
                // destination of the thumbnail header animation. If this is a full screen
                // window scenario, we use the whole display as the target.
                WindowState win = appToken.findMainWindow();
                Rect appRect = win != null ? win.getContentFrameLw() :
                        new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
                Rect insets = win != null ? win.mContentInsets : null;
                // For the new aspect-scaled transition, we want it to always show
                // above the animating opening/closing window, and we want to
                // synchronize its thumbnail surface with the surface for the
                // open/close animation (only on the way down)
                anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
                        insets, thumbnailHeader, taskId, mService.mCurConfiguration.uiMode,
                        mService.mCurConfiguration.orientation);
                openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
                openingAppAnimator.deferThumbnailDestruction =
                        !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
            } else {
                anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
                        displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
            }
            anim.restrictDuration(MAX_ANIMATION_DURATION);
            anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());

            openingAppAnimator.thumbnail = surfaceControl;
            openingAppAnimator.thumbnailLayer = openingLayer;
            openingAppAnimator.thumbnailAnimation = anim;
            mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
        } catch (Surface.OutOfResourcesException e) {
            Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
                    + dirty.width() + " h=" + dirty.height(), e);
            openingAppAnimator.clearThumbnail();
        }
    }

    boolean copyAnimToLayoutParamsLocked() {
        boolean doRequest = false;

        final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
        if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
            mUpdateRotation = true;
            doRequest = true;
        }
        if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
            mWallpaperMayChange = true;
            doRequest = true;
        }
        if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
            mWallpaperForceHidingChanged = true;
            doRequest = true;
        }
        if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
            mOrientationChangeComplete = false;
        } else {
            mOrientationChangeComplete = true;
            mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
            if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
                doRequest = true;
            }
        }
        if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
            mService.mTurnOnScreen = true;
        }
        if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
            mWallpaperActionPending = true;
        }

        return doRequest;
    }

    void requestTraversal() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mService.mH.sendEmptyMessage(DO_TRAVERSAL);
        }
    }

    /**
     * Puts the {@param surface} into a pending list to be destroyed after the current transaction
     * has been committed.
     */
    void destroyAfterTransaction(SurfaceControl surface) {
        mPendingDestroyingSurfaces.add(surface);
    }

    /**
     * Destroys any surfaces that have been put into the pending list with
     * {@link #destroyAfterTransaction}.
     */
    void destroyPendingSurfaces() {
        for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
            mPendingDestroyingSurfaces.get(i).destroy();
        }
        mPendingDestroyingSurfaces.clear();
    }

    public void dump(PrintWriter pw, String prefix) {
        pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
        pw.print(prefix); pw.print("mHoldScreenWindow="); pw.println(mHoldScreenWindow);
        pw.print(prefix); pw.print("mObsuringWindow="); pw.println(mObsuringWindow);
    }
}
