FileDocCategorySizeDatePackage
WindowManagerService.javaAPI DocAndroid 1.5 API369779Wed May 06 22:42:00 BST 2009com.android.server

WindowManagerService

public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor
{@hide}

Fields Summary
static final String
TAG
static final boolean
DEBUG
static final boolean
DEBUG_FOCUS
static final boolean
DEBUG_ANIM
static final boolean
DEBUG_LAYERS
static final boolean
DEBUG_INPUT
static final boolean
DEBUG_INPUT_METHOD
static final boolean
DEBUG_VISIBILITY
static final boolean
DEBUG_ORIENTATION
static final boolean
DEBUG_APP_TRANSITIONS
static final boolean
DEBUG_STARTING_WINDOW
static final boolean
DEBUG_REORDER
static final boolean
SHOW_TRANSACTIONS
static final boolean
PROFILE_ORIENTATION
static final boolean
BLUR
static final boolean
localLOGV
static final int
LOG_WM_NO_SURFACE_MEMORY
static final int
KEY_REPEAT_FIRST_DELAY
How long to wait for first key repeat, in milliseconds
static final int
KEY_REPEAT_DELAY
How long to wait for subsequent key repeats, in milliseconds
static final int
TYPE_LAYER_MULTIPLIER
How much to multiply the policy's type layer, to reserve room for multiple windows of the same type and Z-ordering adjustment with TYPE_LAYER_OFFSET.
static final int
TYPE_LAYER_OFFSET
Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above or below others in the same layer.
static final int
WINDOW_LAYER_MULTIPLIER
How much to increment the layer for each window, to reserve room for effect surfaces between them.
static final int
MAX_ANIMATION_DURATION
The maximum length we will accept for a loaded animation duration: this is 10 seconds.
static final int
DEFAULT_DIM_DURATION
Amount of time (in milliseconds) to animate the dim surface from one value to another, when no window animation is driving it.
static final int
DIM_DURATION_MULTIPLIER
Adjustment to time to perform a dim, to make it more dramatic.
static final int
UPDATE_FOCUS_NORMAL
static final int
UPDATE_FOCUS_WILL_ASSIGN_LAYERS
static final int
UPDATE_FOCUS_PLACING_SURFACES
static final int
UPDATE_FOCUS_WILL_PLACE_SURFACES
private static final String
SYSTEM_SECURE
private boolean
mWaitingUntilKeyguardReenabled
Condition waited on by {@link #reenableKeyguard} to know the call to the window policy has finished.
final android.os.TokenWatcher
mKeyguardDisabled
final android.content.Context
mContext
final boolean
mHaveInputMethods
final boolean
mLimitedAlphaCompositing
final android.view.WindowManagerPolicy
mPolicy
final android.app.IActivityManager
mActivityManager
final com.android.internal.app.IBatteryStats
mBatteryStats
final HashSet
mSessions
All currently active sessions with clients.
final HashMap
mWindowMap
Mapping from an IWindow IBinder to the server's Window object. This is also used as the lock for all of our state.
final HashMap
mTokenMap
Mapping from a token IBinder to a WindowToken object.
final ArrayList
mTokenList
The same tokens as mTokenMap, stored in a list for efficient iteration over them.
final ArrayList
mExitingTokens
Window tokens that are in the process of exiting, but still on screen for animations.
final ArrayList
mAppTokens
Z-ordered (bottom-most first) list of all application tokens, for controlling the ordering of windows in different applications. This contains WindowToken objects.
final ArrayList
mExitingAppTokens
Application tokens that are in the process of exiting, but still on screen for animations.
final ArrayList
mFinishedStarting
List of window tokens that have finished starting their application, and now need to have the policy remove their windows.
final ArrayList
mWindows
Z-ordered (bottom-most first) list of all Window objects.
final ArrayList
mResizingWindows
Windows that are being resized. Used so we can tell the client about the resize after closing the transaction in which we resized the underlying surface.
final ArrayList
mPendingRemove
Windows whose animations have ended and now must be removed.
final ArrayList
mDestroySurface
Windows whose surface should be destroyed.
ArrayList
mLosingFocus
Windows that have lost input focus and are waiting for the new focus window to be displayed before they are told about this.
ArrayList
mForceRemoves
This is set when we have run out of memory, and will either be an empty list or contain windows that need to be force removed.
com.android.internal.view.IInputMethodManager
mInputMethodManager
android.view.SurfaceSession
mFxSession
android.view.Surface
mDimSurface
boolean
mDimShown
float
mDimCurrentAlpha
float
mDimTargetAlpha
float
mDimDeltaPerMs
long
mLastDimAnimTime
android.view.Surface
mBlurSurface
boolean
mBlurShown
int
mTransactionSequence
final float[]
mTmpFloats
boolean
mSafeMode
boolean
mDisplayEnabled
boolean
mSystemBooted
int
mRotation
int
mRequestedRotation
int
mForcedAppOrientation
int
mLastRotationFlags
ArrayList
mRotationWatchers
boolean
mLayoutNeeded
boolean
mAnimationPending
boolean
mDisplayFrozen
boolean
mWindowsFreezingScreen
long
mFreezeGcPending
int
mAppsFreezingScreen
PowerManager.WakeLock
mScreenFrozenLock
int
mNextAppTransition
boolean
mAppTransitionReady
boolean
mAppTransitionTimeout
boolean
mStartingIconInTransition
boolean
mSkipAppTransitionAnimation
final ArrayList
mOpeningApps
final ArrayList
mClosingApps
boolean
mFatTouch
android.view.Display
mDisplay
H
mH
WindowState
mCurrentFocus
WindowState
mLastFocus
WindowState
mInputMethodTarget
WindowState
mUpcomingInputMethodTarget
boolean
mInputMethodTargetWaitingAnim
int
mInputMethodAnimLayerAdjustment
WindowState
mInputMethodWindow
final ArrayList
mInputMethodDialogs
AppWindowToken
mFocusedApp
PowerManagerService
mPowerManager
float
mWindowAnimationScale
float
mTransitionAnimationScale
final KeyWaiter
mKeyWaiter
final KeyQ
mQueue
final InputDispatcherThread
mInputThread
Session
mHoldingScreenOn
boolean
mInTouchMode
Whether the UI is currently running in touch mode (not showing navigational focus because the user is directly pressing the screen).
private ViewServer
mViewServer
final android.graphics.Rect
mTempRect
final android.content.res.Configuration
mTempConfiguration
private static final int
EVENT_NONE
private static final int
EVENT_UNKNOWN
private static final int
EVENT_CHEEK
private static final int
EVENT_IGNORE_DURATION
private static final float
CHEEK_THRESHOLD
private int
mEventState
private float
mEventSize
static final android.view.animation.Animation
sDummyAnimation
private boolean
mInLayout
Constructors Summary
private WindowManagerService(android.content.Context context, PowerManagerService pm, boolean haveInputMethods)

        mContext = context;
        mHaveInputMethods = haveInputMethods;
        mLimitedAlphaCompositing = context.getResources().getBoolean(
                com.android.internal.R.bool.config_sf_limitedAlpha);
        
        mPowerManager = pm;
        mPowerManager.setPolicy(mPolicy);
        PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                "SCREEN_FROZEN");
        mScreenFrozenLock.setReferenceCounted(false);

        mActivityManager = ActivityManagerNative.getDefault();
        mBatteryStats = BatteryStatsService.getService();

        // Get persisted window scale setting
        mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
                Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
        mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
                Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
        
        mQueue = new KeyQ();

        mInputThread = new InputDispatcherThread();
        
        PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
        thr.start();
        
        synchronized (thr) {
            while (!thr.mRunning) {
                try {
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
        }
        
        mInputThread.start();
        
        // Add ourself to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);
    
Methods Summary
public voidaddAppToken(int addPos, android.view.IApplicationToken token, int groupId, int requestedOrientation, boolean fullscreen)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "addAppToken()")) {
            return;
        }
        
        synchronized(mWindowMap) {
            AppWindowToken wtoken = findAppWindowToken(token.asBinder());
            if (wtoken != null) {
                Log.w(TAG, "Attempted to add existing app token: " + token);
                return;
            }
            wtoken = new AppWindowToken(token);
            wtoken.groupId = groupId;
            wtoken.appFullscreen = fullscreen;
            wtoken.requestedOrientation = requestedOrientation;
            mAppTokens.add(addPos, wtoken);
            if (Config.LOGV) Log.v(TAG, "Adding new app token: " + wtoken);
            mTokenMap.put(token.asBinder(), wtoken);
            mTokenList.add(wtoken);
            
            // Application tokens start out hidden.
            wtoken.hidden = true;
            wtoken.hiddenRequested = true;
            
            //dump();
        }
    
voidaddInputMethodWindowToListLocked(com.android.server.WindowManagerService$WindowState win)

        int pos = findDesiredInputMethodWindowIndexLocked(true);
        if (pos >= 0) {
            win.mTargetAppToken = mInputMethodTarget.mAppToken;
            mWindows.add(pos, win);
            moveInputMethodDialogsLocked(pos+1);
            return;
        }
        win.mTargetAppToken = null;
        addWindowToListInOrderLocked(win, true);
        moveInputMethodDialogsLocked(pos);
    
public intaddWindow(com.android.server.WindowManagerService$Session session, android.view.IWindow client, android.view.WindowManager.LayoutParams attrs, int viewVisibility, android.graphics.Rect outContentInsets)

        int res = mPolicy.checkAddPermission(attrs);
        if (res != WindowManagerImpl.ADD_OKAY) {
            return res;
        }
        
        boolean reportNewConfig = false;
        WindowState attachedWindow = null;
        WindowState win = null;
        
        synchronized(mWindowMap) {
            // Instantiating a Display requires talking with the simulator,
            // so don't do it until we know the system is mostly up and
            // running.
            if (mDisplay == null) {
                WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
                mDisplay = wm.getDefaultDisplay();
                mQueue.setDisplay(mDisplay);
                reportNewConfig = true;
            }
            
            if (mWindowMap.containsKey(client.asBinder())) {
                Log.w(TAG, "Window " + client + " is already added");
                return WindowManagerImpl.ADD_DUPLICATE_ADD;
            }

            if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
                attachedWindow = windowForClientLocked(null, attrs.token); 
                if (attachedWindow == null) {
                    Log.w(TAG, "Attempted to add window with token that is not a window: "
                          + attrs.token + ".  Aborting.");
                    return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
                }
                if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
                        && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
                    Log.w(TAG, "Attempted to add window with token that is a sub-window: "
                            + attrs.token + ".  Aborting.");
                    return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
                }
            }

            boolean addToken = false;
            WindowToken token = mTokenMap.get(attrs.token);
            if (token == null) {
                if (attrs.type >= FIRST_APPLICATION_WINDOW
                        && attrs.type <= LAST_APPLICATION_WINDOW) {
                    Log.w(TAG, "Attempted to add application window with unknown token "
                          + attrs.token + ".  Aborting.");
                    return WindowManagerImpl.ADD_BAD_APP_TOKEN;
                }
                if (attrs.type == TYPE_INPUT_METHOD) {
                    Log.w(TAG, "Attempted to add input method window with unknown token "
                          + attrs.token + ".  Aborting.");
                    return WindowManagerImpl.ADD_BAD_APP_TOKEN;
                }
                token = new WindowToken(attrs.token, -1, false);
                addToken = true;
            } else if (attrs.type >= FIRST_APPLICATION_WINDOW
                    && attrs.type <= LAST_APPLICATION_WINDOW) {
                AppWindowToken atoken = token.appWindowToken;
                if (atoken == null) {
                    Log.w(TAG, "Attempted to add window with non-application token "
                          + token + ".  Aborting.");
                    return WindowManagerImpl.ADD_NOT_APP_TOKEN;
                } else if (atoken.removed) {
                    Log.w(TAG, "Attempted to add window with exiting application token "
                          + token + ".  Aborting.");
                    return WindowManagerImpl.ADD_APP_EXITING;
                }
                if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
                    // No need for this guy!
                    if (localLOGV) Log.v(
                            TAG, "**** NO NEED TO START: " + attrs.getTitle());
                    return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
                }
            } else if (attrs.type == TYPE_INPUT_METHOD) {
                if (token.windowType != TYPE_INPUT_METHOD) {
                    Log.w(TAG, "Attempted to add input method window with bad token "
                            + attrs.token + ".  Aborting.");
                      return WindowManagerImpl.ADD_BAD_APP_TOKEN;
                }
            }

            win = new WindowState(session, client, token,
                    attachedWindow, attrs, viewVisibility);
            if (win.mDeathRecipient == null) {
                // Client has apparently died, so there is no reason to
                // continue.
                Log.w(TAG, "Adding window client " + client.asBinder()
                        + " that is dead, aborting.");
                return WindowManagerImpl.ADD_APP_EXITING;
            }

            mPolicy.adjustWindowParamsLw(win.mAttrs);
            
            res = mPolicy.prepareAddWindowLw(win, attrs);
            if (res != WindowManagerImpl.ADD_OKAY) {
                return res;
            }

            // From now on, no exceptions or errors allowed!

            res = WindowManagerImpl.ADD_OKAY;
            
            final long origId = Binder.clearCallingIdentity();
            
            if (addToken) {
                mTokenMap.put(attrs.token, token);
                mTokenList.add(token);
            }
            win.attach();
            mWindowMap.put(client.asBinder(), win);

            if (attrs.type == TYPE_APPLICATION_STARTING &&
                    token.appWindowToken != null) {
                token.appWindowToken.startingWindow = win;
            }

            boolean imMayMove = true;
            
            if (attrs.type == TYPE_INPUT_METHOD) {
                mInputMethodWindow = win;
                addInputMethodWindowToListLocked(win);
                imMayMove = false;
            } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
                mInputMethodDialogs.add(win);
                addWindowToListInOrderLocked(win, true);
                adjustInputMethodDialogsLocked();
                imMayMove = false;
            } else {
                addWindowToListInOrderLocked(win, true);
            }
            
            win.mEnterAnimationPending = true;
            
            mPolicy.getContentInsetHintLw(attrs, outContentInsets);
            
            if (mInTouchMode) {
                res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
            }
            if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
                res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
            }
            
            boolean focusChanged = false;
            if (win.canReceiveKeys()) {
                if ((focusChanged=updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS))
                        == true) {
                    imMayMove = false;
                }
            }
            
            if (imMayMove) {
                moveInputMethodWindowsIfNeededLocked(false);                
            }
            
            assignLayersLocked();
            // Don't do layout here, the window must call
            // relayout to be displayed, so we'll do it there.
            
            //dump();

            if (focusChanged) {
                if (mCurrentFocus != null) {
                    mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
                }
            }
            
            if (localLOGV) Log.v(
                TAG, "New client " + client.asBinder()
                + ": window=" + win);
        }

        // sendNewConfiguration() checks caller permissions so we must call it with
        // privilege.  updateOrientationFromAppTokens() clears and resets the caller
        // identity anyway, so it's safe to just clear & restore around this whole
        // block.
        final long origId = Binder.clearCallingIdentity();
        if (reportNewConfig) {
            sendNewConfiguration();
        } else {
            // Update Orientation after adding a window, only if the window needs to be
            // displayed right away
            if (win.isVisibleOrAdding()) {
                if (updateOrientationFromAppTokens(null, null) != null) {
                    sendNewConfiguration();
                }
            }
        }
        Binder.restoreCallingIdentity(origId);
        
        return res;
    
private voidaddWindowToListInOrderLocked(com.android.server.WindowManagerService$WindowState win, boolean addToToken)

        final IWindow client = win.mClient;
        final WindowToken token = win.mToken;
        final ArrayList localmWindows = mWindows;
        
        final int N = localmWindows.size();
        final WindowState attached = win.mAttachedWindow;
        int i;
        if (attached == null) {
            int tokenWindowsPos = token.windows.size();
            if (token.appWindowToken != null) {
                int index = tokenWindowsPos-1;
                if (index >= 0) {
                    // If this application has existing windows, we
                    // simply place the new window on top of them... but
                    // keep the starting window on top.
                    if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
                        // Base windows go behind everything else.
                        placeWindowBefore(token.windows.get(0), win);
                        tokenWindowsPos = 0;
                    } else {
                        AppWindowToken atoken = win.mAppToken;
                        if (atoken != null &&
                                token.windows.get(index) == atoken.startingWindow) {
                            placeWindowBefore(token.windows.get(index), win);
                            tokenWindowsPos--;
                        } else {
                            int newIdx =  findIdxBasedOnAppTokens(win);
                            if(newIdx != -1) {
                                //there is a window above this one associated with the same 
                                //apptoken note that the window could be a floating window 
                                //that was created later or a window at the top of the list of 
                                //windows associated with this token.
                                localmWindows.add(newIdx+1, win);
                            } 
                        }
                    }
                } else {
                    if (localLOGV) Log.v(
                        TAG, "Figuring out where to add app window "
                        + client.asBinder() + " (token=" + token + ")");
                    // Figure out where the window should go, based on the
                    // order of applications.
                    final int NA = mAppTokens.size();
                    Object pos = null;
                    for (i=NA-1; i>=0; i--) {
                        AppWindowToken t = mAppTokens.get(i);
                        if (t == token) {
                            i--;
                            break;
                        }
                        if (t.windows.size() > 0) {
                            pos = t.windows.get(0);
                        }
                    }
                    // We now know the index into the apps.  If we found
                    // an app window above, that gives us the position; else
                    // we need to look some more.
                    if (pos != null) {
                        // Move behind any windows attached to this one.
                        WindowToken atoken = 
                            mTokenMap.get(((WindowState)pos).mClient.asBinder());
                        if (atoken != null) {
                            final int NC = atoken.windows.size();
                            if (NC > 0) {
                                WindowState bottom = atoken.windows.get(0);
                                if (bottom.mSubLayer < 0) {
                                    pos = bottom;
                                }
                            }
                        }
                        placeWindowBefore(pos, win);
                    } else {
                        while (i >= 0) {
                            AppWindowToken t = mAppTokens.get(i);
                            final int NW = t.windows.size();
                            if (NW > 0) {
                                pos = t.windows.get(NW-1);
                                break;
                            }
                            i--;
                        }
                        if (pos != null) {
                            // Move in front of any windows attached to this
                            // one.
                            WindowToken atoken =
                                mTokenMap.get(((WindowState)pos).mClient.asBinder());
                            if (atoken != null) {
                                final int NC = atoken.windows.size();
                                if (NC > 0) {
                                    WindowState top = atoken.windows.get(NC-1);
                                    if (top.mSubLayer >= 0) {
                                        pos = top;
                                    }
                                }
                            }
                            placeWindowAfter(pos, win);
                        } else {
                            // Just search for the start of this layer.
                            final int myLayer = win.mBaseLayer;
                            for (i=0; i<N; i++) {
                                WindowState w = (WindowState)localmWindows.get(i);
                                if (w.mBaseLayer > myLayer) {
                                    break;
                                }
                            }
                            if (localLOGV || DEBUG_FOCUS) Log.v(
                                TAG, "Adding window " + win + " at "
                                + i + " of " + N);
                            localmWindows.add(i, win);
                        }
                    }
                }
            } else {
                // Figure out where window should go, based on layer.
                final int myLayer = win.mBaseLayer;
                for (i=N-1; i>=0; i--) {
                    if (((WindowState)localmWindows.get(i)).mBaseLayer <= myLayer) {
                        i++;
                        break;
                    }
                }
                if (i < 0) i = 0;
                if (localLOGV || DEBUG_FOCUS) Log.v(
                    TAG, "Adding window " + win + " at "
                    + i + " of " + N);
                localmWindows.add(i, win);
            }
            if (addToToken) {
                token.windows.add(tokenWindowsPos, win);
            }

        } else {
            // Figure out this window's ordering relative to the window
            // it is attached to.
            final int NA = token.windows.size();
            final int sublayer = win.mSubLayer;
            int largestSublayer = Integer.MIN_VALUE;
            WindowState windowWithLargestSublayer = null;
            for (i=0; i<NA; i++) {
                WindowState w = token.windows.get(i);
                final int wSublayer = w.mSubLayer;
                if (wSublayer >= largestSublayer) {
                    largestSublayer = wSublayer;
                    windowWithLargestSublayer = w;
                }
                if (sublayer < 0) {
                    // For negative sublayers, we go below all windows
                    // in the same sublayer.
                    if (wSublayer >= sublayer) {
                        if (addToToken) {
                            token.windows.add(i, win);
                        }
                        placeWindowBefore(
                            wSublayer >= 0 ? attached : w, win);
                        break;
                    }
                } else {
                    // For positive sublayers, we go above all windows
                    // in the same sublayer.
                    if (wSublayer > sublayer) {
                        if (addToToken) {
                            token.windows.add(i, win);
                        }
                        placeWindowBefore(w, win);
                        break;
                    }
                }
            }
            if (i >= NA) {
                if (addToToken) {
                    token.windows.add(win);
                }
                if (sublayer < 0) {
                    placeWindowBefore(attached, win);
                } else {
                    placeWindowAfter(largestSublayer >= 0
                                     ? windowWithLargestSublayer
                                     : attached,
                                     win);
                }
            }
        }
        
        if (win.mAppToken != null && addToToken) {
            win.mAppToken.allAppWindows.add(win);
        }
    
public voidaddWindowToken(android.os.IBinder token, int type)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "addWindowToken()")) {
            return;
        }
        
        synchronized(mWindowMap) {
            WindowToken wtoken = mTokenMap.get(token);
            if (wtoken != null) {
                Log.w(TAG, "Attempted to add existing input method token: " + token);
                return;
            }
            wtoken = new WindowToken(token, type, true);
            mTokenMap.put(token, wtoken);
            mTokenList.add(wtoken);
        }
    
voidadjustInputMethodDialogsLocked()

        moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
    
private booleanapplyAnimationLocked(com.android.server.WindowManagerService$WindowState win, int transit, boolean isEntrance)

        if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
            // If we are trying to apply an animation, but already running
            // an animation of the same type, then just leave that one alone.
            return true;
        }
        
        // Only apply an animation if the display isn't frozen.  If it is
        // frozen, there is no reason to animate and it can cause strange
        // artifacts when we unfreeze the display if some different animation
        // is running.
        if (!mDisplayFrozen) {
            int anim = mPolicy.selectAnimationLw(win, transit);
            int attr = -1;
            Animation a = null;
            if (anim != 0) {
                a = AnimationUtils.loadAnimation(mContext, anim);
            } else {
                switch (transit) {
                    case WindowManagerPolicy.TRANSIT_ENTER:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
                        break;
                    case WindowManagerPolicy.TRANSIT_EXIT:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
                        break;
                    case WindowManagerPolicy.TRANSIT_SHOW:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
                        break;
                    case WindowManagerPolicy.TRANSIT_HIDE:
                        attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
                        break;
                }
                if (attr >= 0) {
                    a = loadAnimation(win.mAttrs, attr);
                }
            }
            if (DEBUG_ANIM) Log.v(TAG, "applyAnimation: win=" + win
                    + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
                    + " mAnimation=" + win.mAnimation
                    + " isEntrance=" + isEntrance);
            if (a != null) {
                if (DEBUG_ANIM) {
                    RuntimeException e = new RuntimeException();
                    e.fillInStackTrace();
                    Log.v(TAG, "Loaded animation " + a + " for " + win, e);
                }
                win.setAnimation(a);
                win.mAnimationIsEntrance = isEntrance;
            }
        } else {
            win.clearAnimation();
        }

        return win.mAnimation != null;
    
private booleanapplyAnimationLocked(com.android.server.WindowManagerService$AppWindowToken wtoken, android.view.WindowManager.LayoutParams lp, int transit, boolean enter)

        // Only apply an animation if the display isn't frozen.  If it is
        // frozen, there is no reason to animate and it can cause strange
        // artifacts when we unfreeze the display if some different animation
        // is running.
        if (!mDisplayFrozen) {
            int animAttr = 0;
            switch (transit) {
                case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
                    animAttr = enter
                            ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
                            : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
                    break;
                case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
                    animAttr = enter
                            ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
                            : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
                    break;
                case WindowManagerPolicy.TRANSIT_TASK_OPEN:
                    animAttr = enter
                            ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
                            : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
                    break;
                case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
                    animAttr = enter
                            ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
                            : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
                    break;
                case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
                    animAttr = enter
                            ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
                            : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
                    break;
                case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
                    animAttr = enter
                            ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
                            : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
                    break;
            }
            Animation a = loadAnimation(lp, animAttr);
            if (DEBUG_ANIM) Log.v(TAG, "applyAnimation: wtoken=" + wtoken
                    + " anim=" + a
                    + " animAttr=0x" + Integer.toHexString(animAttr)
                    + " transit=" + transit);
            if (a != null) {
                if (DEBUG_ANIM) {
                    RuntimeException e = new RuntimeException();
                    e.fillInStackTrace();
                    Log.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
                }
                wtoken.setAnimation(a);
            }
        } else {
            wtoken.clearAnimation();
        }

        return wtoken.animation != null;
    
private voidapplyEnterAnimationLocked(com.android.server.WindowManagerService$WindowState win)

        int transit = WindowManagerPolicy.TRANSIT_SHOW;
        if (win.mEnterAnimationPending) {
            win.mEnterAnimationPending = false;
            transit = WindowManagerPolicy.TRANSIT_ENTER;
        }

        applyAnimationLocked(win, transit, true);
    
private final voidassignLayersLocked()

        int N = mWindows.size();
        int curBaseLayer = 0;
        int curLayer = 0;
        int i;
        
        for (i=0; i<N; i++) {
            WindowState w = (WindowState)mWindows.get(i);
            if (w.mBaseLayer == curBaseLayer || w.mIsImWindow) {
                curLayer += WINDOW_LAYER_MULTIPLIER;
                w.mLayer = curLayer;
            } else {
                curBaseLayer = curLayer = w.mBaseLayer;
                w.mLayer = curLayer;
            }
            if (w.mTargetAppToken != null) {
                w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
            } else if (w.mAppToken != null) {
                w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
            } else {
                w.mAnimLayer = w.mLayer;
            }
            if (w.mIsImWindow) {
                w.mAnimLayer += mInputMethodAnimLayerAdjustment;
            }
            if (DEBUG_LAYERS) Log.v(TAG, "Assign layer " + w + ": "
                    + w.mAnimLayer);
            //System.out.println(
            //    "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
        }
    
static booleancanBeImeTarget(com.android.server.WindowManagerService$WindowState w)

        final int fl = w.mAttrs.flags
                & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
        if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
            return w.isVisibleOrAdding();
        }
        return false;
    
booleancheckCallingPermission(java.lang.String permission, java.lang.String func)

        // Quick check: if the calling permission is me, it's all okay.
        if (Binder.getCallingPid() == Process.myPid()) {
            return true;
        }
        
        if (mContext.checkCallingPermission(permission)
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        String msg = "Permission Denial: " + func + " from pid="
                + Binder.getCallingPid()
                + ", uid=" + Binder.getCallingUid()
                + " requires " + permission;
        Log.w(TAG, msg);
        return false;
    
private com.android.server.WindowManagerService$WindowStatecomputeFocusedWindowLocked()

        WindowState result = null;
        WindowState win;

        int i = mWindows.size() - 1;
        int nextAppIndex = mAppTokens.size()-1;
        WindowToken nextApp = nextAppIndex >= 0
            ? mAppTokens.get(nextAppIndex) : null;

        while (i >= 0) {
            win = (WindowState)mWindows.get(i);

            if (localLOGV || DEBUG_FOCUS) Log.v(
                TAG, "Looking for focus: " + i
                + " = " + win
                + ", flags=" + win.mAttrs.flags
                + ", canReceive=" + win.canReceiveKeys());

            AppWindowToken thisApp = win.mAppToken;
            
            // If this window's application has been removed, just skip it.
            if (thisApp != null && thisApp.removed) {
                i--;
                continue;
            }
            
            // If there is a focused app, don't allow focus to go to any
            // windows below it.  If this is an application window, step
            // through the app tokens until we find its app.
            if (thisApp != null && nextApp != null && thisApp != nextApp
                    && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
                int origAppIndex = nextAppIndex;
                while (nextAppIndex > 0) {
                    if (nextApp == mFocusedApp) {
                        // Whoops, we are below the focused app...  no focus
                        // for you!
                        if (localLOGV || DEBUG_FOCUS) Log.v(
                            TAG, "Reached focused app: " + mFocusedApp);
                        return null;
                    }
                    nextAppIndex--;
                    nextApp = mAppTokens.get(nextAppIndex);
                    if (nextApp == thisApp) {
                        break;
                    }
                }
                if (thisApp != nextApp) {
                    // Uh oh, the app token doesn't exist!  This shouldn't
                    // happen, but if it does we can get totally hosed...
                    // so restart at the original app.
                    nextAppIndex = origAppIndex;
                    nextApp = mAppTokens.get(nextAppIndex);
                }
            }

            // Dispatch to this window if it is wants key events.
            if (win.canReceiveKeys()) {
                if (DEBUG_FOCUS) Log.v(
                        TAG, "Found focus @ " + i + " = " + win);
                result = win;
                break;
            }

            i--;
        }

        return result;
    
intcomputeForcedAppOrientationLocked()

        int req = getOrientationFromWindowsLocked();
        if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
            req = getOrientationFromAppTokensLocked();
        }
        return req;
    
public android.content.res.ConfigurationcomputeNewConfiguration()

        synchronized (mWindowMap) {
            return computeNewConfigurationLocked();
        }
    
android.content.res.ConfigurationcomputeNewConfigurationLocked()

        Configuration config = new Configuration();
        if (!computeNewConfigurationLocked(config)) {
            return null;
        }
        Log.i(TAG, "Config changed: " + config);
        long now = SystemClock.uptimeMillis();
        //Log.i(TAG, "Config changing, gc pending: " + mFreezeGcPending + ", now " + now);
        if (mFreezeGcPending != 0) {
            if (now > (mFreezeGcPending+1000)) {
                //Log.i(TAG, "Gc!  " + now + " > " + (mFreezeGcPending+1000));
                mH.removeMessages(H.FORCE_GC);
                Runtime.getRuntime().gc();
                mFreezeGcPending = now;
            }
        } else {
            mFreezeGcPending = now;
        }
        return config;
    
booleancomputeNewConfigurationLocked(android.content.res.Configuration config)

        if (mDisplay == null) {
            return false;
        }
        mQueue.getInputConfiguration(config);
        final int dw = mDisplay.getWidth();
        final int dh = mDisplay.getHeight();
        int orientation = Configuration.ORIENTATION_SQUARE;
        if (dw < dh) {
            orientation = Configuration.ORIENTATION_PORTRAIT;
        } else if (dw > dh) {
            orientation = Configuration.ORIENTATION_LANDSCAPE;
        }
        config.orientation = orientation;
        config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
        config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
        mPolicy.adjustConfigurationLw(config);
        return true;
    
public booleandetectSafeMode()

        mSafeMode = mPolicy.detectSafeMode();
        return mSafeMode;
    
public voiddisableKeyguard(android.os.IBinder token, java.lang.String tag)

        if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
            != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
        }
        mKeyguardDisabled.acquire(token, tag);
    
private booleandispatchKey(android.view.KeyEvent event, int pid, int uid)

return
Returns true if event was dispatched, false if it was dropped for any reason

        if (DEBUG_INPUT) Log.v(TAG, "Dispatch key: " + event);

        Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
                null, false, false);
        if (focusObj == null) {
            Log.w(TAG, "No focus window, dropping: " + event);
            return false;
        }
        if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
            return true;
        }
        
        WindowState focus = (WindowState)focusObj;
        
        if (DEBUG_INPUT) Log.v(
            TAG, "Dispatching to " + focus + ": " + event);

        if (uid != 0 && uid != focus.mSession.mUid) {
            if (mContext.checkPermission(
                    android.Manifest.permission.INJECT_EVENTS, pid, uid)
                    != PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "Permission denied: injecting key event from pid "
                        + pid + " uid " + uid + " to window " + focus
                        + " owned by uid " + focus.mSession.mUid);
                return false;
            }
        }
        
        synchronized(mWindowMap) {
            mKeyWaiter.bindTargetWindowLocked(focus);
        }

        // NOSHIP extra state logging
        mKeyWaiter.recordDispatchState(event, focus);
        // END NOSHIP
        
        try {
            if (DEBUG_INPUT || DEBUG_FOCUS) {
                Log.v(TAG, "Delivering key " + event.getKeyCode()
                        + " to " + focus);
            }
            focus.mClient.dispatchKey(event);
            return true;
        } catch (android.os.RemoteException e) {
            Log.i(TAG, "WINDOW DIED during key dispatch: " + focus);
            try {
                removeWindow(focus.mSession, focus.mClient);
            } catch (java.util.NoSuchElementException ex) {
                // This will happen if the window has already been
                // removed.
            }
        }
        
        return false;
    
private booleandispatchPointer(com.android.server.KeyInputQueue.QueuedEvent qev, android.view.MotionEvent ev, int pid, int uid)

return
Returns true if event was dispatched, false if it was dropped for any reason

        if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Log.v(TAG,
                "dispatchPointer " + ev);

        Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
                ev, true, false);
        
        int action = ev.getAction();
        
        if (action == MotionEvent.ACTION_UP) {
            // let go of our target
            mKeyWaiter.mMotionTarget = null;
            mPowerManager.logPointerUpEvent();
        } else if (action == MotionEvent.ACTION_DOWN) {
            mPowerManager.logPointerDownEvent();
        }

        if (targetObj == null) {
            // In this case we are either dropping the event, or have received
            // a move or up without a down.  It is common to receive move
            // events in such a way, since this means the user is moving the
            // pointer without actually pressing down.  All other cases should
            // be atypical, so let's log them.
            if (ev.getAction() != MotionEvent.ACTION_MOVE) {
                Log.w(TAG, "No window to dispatch pointer action " + ev.getAction());
            }
            if (qev != null) {
                mQueue.recycleEvent(qev);
            }
            ev.recycle();
            return false;
        }
        if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
            if (qev != null) {
                mQueue.recycleEvent(qev);
            }
            ev.recycle();
            return true;
        }
        
        WindowState target = (WindowState)targetObj;
        
        final long eventTime = ev.getEventTime();
        
        //Log.i(TAG, "Sending " + ev + " to " + target);

        if (uid != 0 && uid != target.mSession.mUid) {
            if (mContext.checkPermission(
                    android.Manifest.permission.INJECT_EVENTS, pid, uid)
                    != PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "Permission denied: injecting pointer event from pid "
                        + pid + " uid " + uid + " to window " + target
                        + " owned by uid " + target.mSession.mUid);
                if (qev != null) {
                    mQueue.recycleEvent(qev);
                }
                ev.recycle();
                return false;
            }
        }
        
        if ((target.mAttrs.flags & 
                        WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
            //target wants to ignore fat touch events
            boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
            //explicit flag to return without processing event further
            boolean returnFlag = false;
            if((action == MotionEvent.ACTION_DOWN)) {
                mFatTouch = false;
                if(cheekPress) {
                    mFatTouch = true;
                    returnFlag = true;
                }
            } else {
                if(action == MotionEvent.ACTION_UP) {
                    if(mFatTouch) {
                        //earlier even was invalid doesnt matter if current up is cheekpress or not
                        mFatTouch = false;
                        returnFlag = true;
                    } else if(cheekPress) {
                        //cancel the earlier event
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        action = MotionEvent.ACTION_CANCEL;
                    }
                } else if(action == MotionEvent.ACTION_MOVE) {
                    if(mFatTouch) {
                        //two cases here
                        //an invalid down followed by 0 or moves(valid or invalid)
                        //a valid down,  invalid move, more moves. want to ignore till up 
                        returnFlag = true;
                    } else if(cheekPress) {
                        //valid down followed by invalid moves
                        //an invalid move have to cancel earlier action
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        action = MotionEvent.ACTION_CANCEL;
                        if (DEBUG_INPUT) Log.v(TAG, "Sending cancel for invalid ACTION_MOVE");
                        //note that the subsequent invalid moves will not get here
                        mFatTouch = true;
                    }
                }
            } //else if action
            if(returnFlag) {
                //recycle que, ev
                if (qev != null) {
                    mQueue.recycleEvent(qev);
                }
                ev.recycle();
                return false;
            }
        } //end if target
        
        synchronized(mWindowMap) {
            if (qev != null && action == MotionEvent.ACTION_MOVE) {
                mKeyWaiter.bindTargetWindowLocked(target,
                        KeyWaiter.RETURN_PENDING_POINTER, qev);
                ev = null;
            } else {
                if (action == MotionEvent.ACTION_DOWN) {
                    WindowState out = mKeyWaiter.mOutsideTouchTargets;
                    if (out != null) {
                        MotionEvent oev = MotionEvent.obtain(ev);
                        oev.setAction(MotionEvent.ACTION_OUTSIDE);
                        do {
                            final Rect frame = out.mFrame;
                            oev.offsetLocation(-(float)frame.left, -(float)frame.top);
                            try {
                                out.mClient.dispatchPointer(oev, eventTime);
                            } catch (android.os.RemoteException e) {
                                Log.i(TAG, "WINDOW DIED during outside motion dispatch: " + out);
                            }
                            oev.offsetLocation((float)frame.left, (float)frame.top);
                            out = out.mNextOutsideTouch;
                        } while (out != null);
                        mKeyWaiter.mOutsideTouchTargets = null;
                    }
                }
                final Rect frame = target.mFrame;
                ev.offsetLocation(-(float)frame.left, -(float)frame.top);
                mKeyWaiter.bindTargetWindowLocked(target);
            }
        }
        
        // finally offset the event to the target's coordinate system and
        // dispatch the event.
        try {
            if (DEBUG_INPUT || DEBUG_FOCUS || WindowManagerPolicy.WATCH_POINTER) {
                Log.v(TAG, "Delivering pointer " + qev + " to " + target);
            }
            target.mClient.dispatchPointer(ev, eventTime);
            return true;
        } catch (android.os.RemoteException e) {
            Log.i(TAG, "WINDOW DIED during motion dispatch: " + target);
            mKeyWaiter.mMotionTarget = null;
            try {
                removeWindow(target.mSession, target.mClient);
            } catch (java.util.NoSuchElementException ex) {
                // This will happen if the window has already been
                // removed.
            }
        }
        return false;
    
private booleandispatchTrackball(com.android.server.KeyInputQueue.QueuedEvent qev, android.view.MotionEvent ev, int pid, int uid)

return
Returns true if event was dispatched, false if it was dropped for any reason

        if (DEBUG_INPUT) Log.v(
                TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
        
        Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
                ev, false, false);
        if (focusObj == null) {
            Log.w(TAG, "No focus window, dropping trackball: " + ev);
            if (qev != null) {
                mQueue.recycleEvent(qev);
            }
            ev.recycle();
            return false;
        }
        if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
            if (qev != null) {
                mQueue.recycleEvent(qev);
            }
            ev.recycle();
            return true;
        }
        
        WindowState focus = (WindowState)focusObj;
        
        if (uid != 0 && uid != focus.mSession.mUid) {
            if (mContext.checkPermission(
                    android.Manifest.permission.INJECT_EVENTS, pid, uid)
                    != PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "Permission denied: injecting key event from pid "
                        + pid + " uid " + uid + " to window " + focus
                        + " owned by uid " + focus.mSession.mUid);
                if (qev != null) {
                    mQueue.recycleEvent(qev);
                }
                ev.recycle();
                return false;
            }
        }
        
        final long eventTime = ev.getEventTime();
        
        synchronized(mWindowMap) {
            if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
                mKeyWaiter.bindTargetWindowLocked(focus,
                        KeyWaiter.RETURN_PENDING_TRACKBALL, qev);
                // We don't deliver movement events to the client, we hold
                // them and wait for them to call back.
                ev = null;
            } else {
                mKeyWaiter.bindTargetWindowLocked(focus);
            }
        }
        
        try {
            focus.mClient.dispatchTrackball(ev, eventTime);
            return true;
        } catch (android.os.RemoteException e) {
            Log.i(TAG, "WINDOW DIED during key dispatch: " + focus);
            try {
                removeWindow(focus.mSession, focus.mClient);
            } catch (java.util.NoSuchElementException ex) {
                // This will happen if the window has already been
                // removed.
            }
        }
        
        return false;
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump WindowManager from from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
            return;
        }
        
        synchronized(mWindowMap) {
            pw.println("Current Window Manager state:");
            for (int i=mWindows.size()-1; i>=0; i--) {
                WindowState w = (WindowState)mWindows.get(i);
                pw.println("  Window #" + i + ":");
                w.dump(pw, "    ");
            }
            if (mInputMethodDialogs.size() > 0) {
                pw.println(" ");
                pw.println("  Input method dialogs:");
                for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
                    WindowState w = mInputMethodDialogs.get(i);
                    pw.println("  IM Dialog #" + i + ": " + w);
                }
            }
            if (mPendingRemove.size() > 0) {
                pw.println(" ");
                pw.println("  Remove pending for:");
                for (int i=mPendingRemove.size()-1; i>=0; i--) {
                    WindowState w = mPendingRemove.get(i);
                    pw.println("  Remove #" + i + ":");
                    w.dump(pw, "    ");
                }
            }
            if (mForceRemoves != null && mForceRemoves.size() > 0) {
                pw.println(" ");
                pw.println("  Windows force removing:");
                for (int i=mForceRemoves.size()-1; i>=0; i--) {
                    WindowState w = mForceRemoves.get(i);
                    pw.println("  Removing #" + i + ":");
                    w.dump(pw, "    ");
                }
            }
            if (mDestroySurface.size() > 0) {
                pw.println(" ");
                pw.println("  Windows waiting to destroy their surface:");
                for (int i=mDestroySurface.size()-1; i>=0; i--) {
                    WindowState w = mDestroySurface.get(i);
                    pw.println("  Destroy #" + i + ":");
                    w.dump(pw, "    ");
                }
            }
            if (mLosingFocus.size() > 0) {
                pw.println(" ");
                pw.println("  Windows losing focus:");
                for (int i=mLosingFocus.size()-1; i>=0; i--) {
                    WindowState w = mLosingFocus.get(i);
                    pw.println("  Losing #" + i + ":");
                    w.dump(pw, "    ");
                }
            }
            if (mSessions.size() > 0) {
                pw.println(" ");
                pw.println("  All active sessions:");
                Iterator<Session> it = mSessions.iterator();
                while (it.hasNext()) {
                    Session s = it.next();
                    pw.println("  Session " + s);
                    s.dump(pw, "    ");
                }
            }
            if (mTokenMap.size() > 0) {
                pw.println(" ");
                pw.println("  All tokens:");
                Iterator<WindowToken> it = mTokenMap.values().iterator();
                while (it.hasNext()) {
                    WindowToken token = it.next();
                    pw.println("  Token " + token.token);
                    token.dump(pw, "    ");
                }
            }
            if (mTokenList.size() > 0) {
                pw.println(" ");
                pw.println("  Window token list:");
                for (int i=0; i<mTokenList.size(); i++) {
                    pw.println("  WindowToken #" + i + ": " + mTokenList.get(i));
                }
            }
            if (mAppTokens.size() > 0) {
                pw.println(" ");
                pw.println("  Application tokens in Z order:");
                for (int i=mAppTokens.size()-1; i>=0; i--) {
                    pw.println("  AppWindowToken #" + i + ": " + mAppTokens.get(i));
                }
            }
            if (mFinishedStarting.size() > 0) {
                pw.println(" ");
                pw.println("  Finishing start of application tokens:");
                for (int i=mFinishedStarting.size()-1; i>=0; i--) {
                    WindowToken token = mFinishedStarting.get(i);
                    pw.println("  Finish Starting App Token #" + i + ":");
                    token.dump(pw, "    ");
                }
            }
            if (mExitingTokens.size() > 0) {
                pw.println(" ");
                pw.println("  Exiting tokens:");
                for (int i=mExitingTokens.size()-1; i>=0; i--) {
                    WindowToken token = mExitingTokens.get(i);
                    pw.println("  Exiting Token #" + i + ":");
                    token.dump(pw, "    ");
                }
            }
            if (mExitingAppTokens.size() > 0) {
                pw.println(" ");
                pw.println("  Exiting application tokens:");
                for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
                    WindowToken token = mExitingAppTokens.get(i);
                    pw.println("  Exiting App Token #" + i + ":");
                    token.dump(pw, "    ");
                }
            }
            pw.println(" ");
            pw.println("  mCurrentFocus=" + mCurrentFocus);
            pw.println("  mLastFocus=" + mLastFocus);
            pw.println("  mFocusedApp=" + mFocusedApp);
            pw.println("  mInputMethodTarget=" + mInputMethodTarget);
            pw.println("  mInputMethodWindow=" + mInputMethodWindow);
            pw.println("  mInTouchMode=" + mInTouchMode);
            pw.println("  mSystemBooted=" + mSystemBooted
                    + " mDisplayEnabled=" + mDisplayEnabled);
            pw.println("  mLayoutNeeded=" + mLayoutNeeded
                    + " mBlurShown=" + mBlurShown);
            pw.println("  mDimShown=" + mDimShown
                    + " current=" + mDimCurrentAlpha
                    + " target=" + mDimTargetAlpha
                    + " delta=" + mDimDeltaPerMs
                    + " lastAnimTime=" + mLastDimAnimTime);
            pw.println("  mInputMethodAnimLayerAdjustment="
                    + mInputMethodAnimLayerAdjustment);
            pw.println("  mDisplayFrozen=" + mDisplayFrozen
                    + " mWindowsFreezingScreen=" + mWindowsFreezingScreen
                    + " mAppsFreezingScreen=" + mAppsFreezingScreen);
            pw.println("  mRotation=" + mRotation
                    + ", mForcedAppOrientation=" + mForcedAppOrientation
                    + ", mRequestedRotation=" + mRequestedRotation);
            pw.println("  mAnimationPending=" + mAnimationPending
                    + " mWindowAnimationScale=" + mWindowAnimationScale
                    + " mTransitionWindowAnimationScale=" + mTransitionAnimationScale);
            pw.println("  mNextAppTransition=0x"
                    + Integer.toHexString(mNextAppTransition)
                    + ", mAppTransitionReady=" + mAppTransitionReady
                    + ", mAppTransitionTimeout=" + mAppTransitionTimeout);
            pw.println("  mStartingIconInTransition=" + mStartingIconInTransition
                    + ", mSkipAppTransitionAnimation=" + mSkipAppTransitionAnimation);
            pw.println("  mOpeningApps=" + mOpeningApps);
                    pw.println("  mClosingApps=" + mClosingApps);
            pw.println("  DisplayWidth=" + mDisplay.getWidth()
                    + " DisplayHeight=" + mDisplay.getHeight());
            pw.println("  KeyWaiter state:");
            pw.println("    mLastWin=" + mKeyWaiter.mLastWin
                    + " mLastBinder=" + mKeyWaiter.mLastBinder);
            pw.println("    mFinished=" + mKeyWaiter.mFinished
                    + " mGotFirstWindow=" + mKeyWaiter.mGotFirstWindow
                    + " mEventDispatching=" + mKeyWaiter.mEventDispatching
                    + " mTimeToSwitch=" + mKeyWaiter.mTimeToSwitch);
        }
    
voiddumpAppTokensLocked()

        for (int i=mAppTokens.size()-1; i>=0; i--) {
            Log.v(TAG, "  #" + i + ": " + mAppTokens.get(i).token);
        }
    
voiddumpWindowsLocked()

        for (int i=mWindows.size()-1; i>=0; i--) {
            Log.v(TAG, "  #" + i + ": " + mWindows.get(i));
        }
    
public voidenableScreenAfterBoot()

        synchronized(mWindowMap) {
            if (mSystemBooted) {
                return;
            }
            mSystemBooted = true;
        }
        
        performEnableScreen();
    
public voidenableScreenIfNeededLocked()

        if (mDisplayEnabled) {
            return;
        }
        if (!mSystemBooted) {
            return;
        }
        mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
    
private inteventType(android.view.MotionEvent ev)


        
        float size = ev.getSize();
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mEventSize = size;
            return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_EVENT;
        case MotionEvent.ACTION_UP:
            if (size > mEventSize) mEventSize = size;
            return (mEventSize > CHEEK_THRESHOLD) ? CHEEK_EVENT : TOUCH_UP_EVENT;
        case MotionEvent.ACTION_MOVE:
            final int N = ev.getHistorySize();
            if (size > mEventSize) mEventSize = size;
            if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
            for (int i=0; i<N; i++) {
                size = ev.getHistoricalSize(i);
                if (size > mEventSize) mEventSize = size;
                if (mEventSize > CHEEK_THRESHOLD) return CHEEK_EVENT;
            }
            if (ev.getEventTime() < ev.getDownTime() + EVENT_IGNORE_DURATION) {
                return TOUCH_EVENT;
            } else {
                return LONG_TOUCH_EVENT;
            }
        default:
            // not good
            return OTHER_EVENT;
        }
    
public voidexecuteAppTransition()

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "executeAppTransition()")) {
            return;
        }
        
        synchronized(mWindowMap) {
            if (DEBUG_APP_TRANSITIONS) Log.v(
                    TAG, "Execute app transition: mNextAppTransition=" + mNextAppTransition);
            if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
                mAppTransitionReady = true;
                final long origId = Binder.clearCallingIdentity();
                performLayoutAndPlaceSurfacesLocked();
                Binder.restoreCallingIdentity(origId);
            }
        }
    
public voidexitKeyguardSecurely(android.view.IOnKeyguardExitResult callback)

see
android.app.KeyguardManager#exitKeyguardSecurely

        if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
            != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
        }
        mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
            public void onKeyguardExitResult(boolean success) {
                try {
                    callback.onKeyguardExitResult(success);
                } catch (RemoteException e) {
                    // Client has died, we don't care.
                }
            }
        });
    
public static android.view.WindowManager.LayoutParamsfindAnimations(java.util.ArrayList order, java.util.ArrayList tokenList1, java.util.ArrayList tokenList2)

        // We need to figure out which animation to use...
        WindowManager.LayoutParams animParams = null;
        int animSrc = 0;
        
        //Log.i(TAG, "Looking for animations...");
        for (int i=order.size()-1; i>=0; i--) {
            AppWindowToken wtoken = order.get(i);
            //Log.i(TAG, "Token " + wtoken + " with " + wtoken.windows.size() + " windows");
            if (tokenList1.contains(wtoken) || tokenList2.contains(wtoken)) {
                int j = wtoken.windows.size();
                while (j > 0) {
                    j--;
                    WindowState win = wtoken.windows.get(j);
                    //Log.i(TAG, "Window " + win + ": type=" + win.mAttrs.type);
                    if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
                            || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
                        //Log.i(TAG, "Found base or application window, done!");
                        if (wtoken.appFullscreen) {
                            return win.mAttrs;
                        }
                        if (animSrc < 2) {
                            animParams = win.mAttrs;
                            animSrc = 2;
                        }
                    } else if (animSrc < 1 && win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION) {
                        //Log.i(TAG, "Found normal window, we may use this...");
                        animParams = win.mAttrs;
                        animSrc = 1;
                    }
                }
            }
        }
        
        return animParams;
    
com.android.server.WindowManagerService$AppWindowTokenfindAppWindowToken(android.os.IBinder token)

        WindowToken wtoken = mTokenMap.get(token);
        if (wtoken == null) {
            return null;
        }
        return wtoken.appWindowToken;
    
intfindDesiredInputMethodWindowIndexLocked(boolean willMove)

        final ArrayList localmWindows = mWindows;
        final int N = localmWindows.size();
        WindowState w = null;
        int i = N;
        while (i > 0) {
            i--;
            w = (WindowState)localmWindows.get(i);
            
            //Log.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
            //        + Integer.toHexString(w.mAttrs.flags));
            if (canBeImeTarget(w)) {
                //Log.i(TAG, "Putting input method here!");
                
                // Yet more tricksyness!  If this window is a "starting"
                // window, we do actually want to be on top of it, but
                // it is not -really- where input will go.  So if the caller
                // is not actually looking to move the IME, look down below
                // for a real window to target...
                if (!willMove
                        && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
                        && i > 0) {
                    WindowState wb = (WindowState)localmWindows.get(i-1);
                    if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
                        i--;
                        w = wb;
                    }
                }
                break;
            }
        }
        
        mUpcomingInputMethodTarget = w;
        
        if (DEBUG_INPUT_METHOD) Log.v(TAG, "Desired input method target="
                + w + " willMove=" + willMove);
        
        if (willMove && w != null) {
            final WindowState curTarget = mInputMethodTarget;
            if (curTarget != null && curTarget.mAppToken != null) {
                
                // Now some fun for dealing with window animations that
                // modify the Z order.  We need to look at all windows below
                // the current target that are in this app, finding the highest
                // visible one in layering.
                AppWindowToken token = curTarget.mAppToken;
                WindowState highestTarget = null;
                int highestPos = 0;
                if (token.animating || token.animation != null) {
                    int pos = 0;
                    pos = localmWindows.indexOf(curTarget);
                    while (pos >= 0) {
                        WindowState win = (WindowState)localmWindows.get(pos);
                        if (win.mAppToken != token) {
                            break;
                        }
                        if (!win.mRemoved) {
                            if (highestTarget == null || win.mAnimLayer >
                                    highestTarget.mAnimLayer) {
                                highestTarget = win;
                                highestPos = pos;
                            }
                        }
                        pos--;
                    }
                }
                
                if (highestTarget != null) {
                    if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition=" 
                            + mNextAppTransition + " " + highestTarget
                            + " animating=" + highestTarget.isAnimating()
                            + " layer=" + highestTarget.mAnimLayer
                            + " new layer=" + w.mAnimLayer);
                    
                    if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
                        // If we are currently setting up for an animation,
                        // hold everything until we can find out what will happen.
                        mInputMethodTargetWaitingAnim = true;
                        mInputMethodTarget = highestTarget;
                        return highestPos + 1;
                    } else if (highestTarget.isAnimating() &&
                            highestTarget.mAnimLayer > w.mAnimLayer) {
                        // If the window we are currently targeting is involved
                        // with an animation, and it is on top of the next target
                        // we will be over, then hold off on moving until
                        // that is done.
                        mInputMethodTarget = highestTarget;
                        return highestPos + 1;
                    }
                }
            }
        }
        
        //Log.i(TAG, "Placing input method @" + (i+1));
        if (w != null) {
            if (willMove) {
                RuntimeException e = new RuntimeException();
                e.fillInStackTrace();
                if (DEBUG_INPUT_METHOD) Log.w(TAG, "Moving IM target from "
                        + mInputMethodTarget + " to " + w, e);
                mInputMethodTarget = w;
                if (w.mAppToken != null) {
                    setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
                } else {
                    setInputMethodAnimLayerAdjustment(0);
                }
            }
            return i+1;
        }
        if (willMove) {
            RuntimeException e = new RuntimeException();
            e.fillInStackTrace();
            if (DEBUG_INPUT_METHOD) Log.w(TAG, "Moving IM target from "
                    + mInputMethodTarget + " to null", e);
            mInputMethodTarget = null;
            setInputMethodAnimLayerAdjustment(0);
        }
        return -1;
    
private intfindIdxBasedOnAppTokens(com.android.server.WindowManagerService$WindowState win)

        //use a local variable to cache mWindows
        ArrayList localmWindows = mWindows;
        int jmax = localmWindows.size();
        if(jmax == 0) {
            return -1;
        }
        for(int j = (jmax-1); j >= 0; j--) {
            WindowState wentry = (WindowState)localmWindows.get(j);
            if(wentry.mAppToken == win.mAppToken) {
                return j;
            }
        }
        return -1;
    
private com.android.server.WindowManagerService$WindowStatefindWindow(int hashCode)

        if (hashCode == -1) {
            return getFocusedWindow();
        }

        synchronized (mWindowMap) {
            final ArrayList windows = mWindows;
            final int count = windows.size();

            for (int i = 0; i < count; i++) {
                WindowState w = (WindowState) windows.get(i);
                if (System.identityHashCode(w) == hashCode) {
                    return w;
                }
            }
        }

        return null;
    
private intfindWindowOffsetLocked(int tokenPos)

        final int NW = mWindows.size();

        if (tokenPos >= mAppTokens.size()) {
            int i = NW;
            while (i > 0) {
                i--;
                WindowState win = (WindowState)mWindows.get(i);
                if (win.getAppToken() != null) {
                    return i+1;
                }
            }
        }

        while (tokenPos > 0) {
            // Find the first app token below the new position that has
            // a window displayed.
            final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
            if (DEBUG_REORDER) Log.v(TAG, "Looking for lower windows @ "
                    + tokenPos + " -- " + wtoken.token);
            int i = wtoken.windows.size();
            while (i > 0) {
                i--;
                WindowState win = wtoken.windows.get(i);
                int j = win.mChildWindows.size();
                while (j > 0) {
                    j--;
                    WindowState cwin = (WindowState)win.mChildWindows.get(j);
                    if (cwin.mSubLayer >= 0 ) {
                        for (int pos=NW-1; pos>=0; pos--) {
                            if (mWindows.get(pos) == cwin) {
                                if (DEBUG_REORDER) Log.v(TAG,
                                        "Found child win @" + (pos+1));
                                return pos+1;
                            }
                        }
                    }
                }
                for (int pos=NW-1; pos>=0; pos--) {
                    if (mWindows.get(pos) == win) {
                        if (DEBUG_REORDER) Log.v(TAG, "Found win @" + (pos+1));
                        return pos+1;
                    }
                }
            }
            tokenPos--;
        }

        return 0;
    
public voidfinishDrawingWindow(com.android.server.WindowManagerService$Session session, android.view.IWindow client)

        final long origId = Binder.clearCallingIdentity();
        synchronized(mWindowMap) {
            WindowState win = windowForClientLocked(session, client);
            if (win != null && win.finishDrawingLocked()) {
                mLayoutNeeded = true;
                performLayoutAndPlaceSurfacesLocked();
            }
        }
        Binder.restoreCallingIdentity(origId);
    
static floatfixScale(float scale)

        if (scale < 0) scale = 0;
        else if (scale > 20) scale = 20;
        return Math.abs(scale);
    
public floatgetAnimationScale(int which)

        switch (which) {
            case 0: return mWindowAnimationScale;
            case 1: return mTransitionAnimationScale;
        }
        return 0;
    
public float[]getAnimationScales()

        return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
    
public intgetAppOrientation(android.view.IApplicationToken token)

        synchronized(mWindowMap) {
            AppWindowToken wtoken = findAppWindowToken(token.asBinder());
            if (wtoken == null) {
                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
            }
            
            return wtoken.requestedOrientation;
        }
    
private AttributeCache.EntrygetCachedAnimations(android.view.WindowManager.LayoutParams lp)

        if (DEBUG_ANIM) Log.v(TAG, "Loading animations: params package="
                + (lp != null ? lp.packageName : null)
                + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
        if (lp != null && lp.windowAnimations != 0) {
            // If this is a system resource, don't try to load it from the
            // application resources.  It is nice to avoid loading application
            // resources if we can.
            String packageName = lp.packageName != null ? lp.packageName : "android";
            int resId = lp.windowAnimations;
            if ((resId&0xFF000000) == 0x01000000) {
                packageName = "android";
            }
            if (DEBUG_ANIM) Log.v(TAG, "Loading animations: picked package="
                    + packageName);
            return AttributeCache.instance().get(packageName, resId,
                    com.android.internal.R.styleable.WindowAnimation);
        }
        return null;
    
private com.android.server.WindowManagerService$WindowStategetFocusedWindow()

        synchronized (mWindowMap) {
            return getFocusedWindowLocked();
        }
    
private com.android.server.WindowManagerService$WindowStategetFocusedWindowLocked()

        return mCurrentFocus;
    
public intgetKeycodeState(int sw)

        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                "getKeycodeState()")) {
            return -1;
        }
        return KeyInputQueue.getKeycodeState(sw);
    
public intgetKeycodeStateForDevice(int devid, int sw)

        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                "getKeycodeStateForDevice()")) {
            return -1;
        }
        return KeyInputQueue.getKeycodeState(devid, sw);
    
public intgetOrientationFromAppTokensLocked()

            int pos = mAppTokens.size() - 1;
            int curGroup = 0;
            int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
            boolean haveGroup = false;
            boolean lastFullscreen = false;
            while (pos >= 0) {
                AppWindowToken wtoken = mAppTokens.get(pos);
                pos--;
                // if we're about to tear down this window, don't use it for orientation
                if (!wtoken.hidden && wtoken.hiddenRequested) {
                    continue;
                }

                if (!haveGroup) {
                    // We ignore any hidden applications on the top.
                    if (wtoken.hiddenRequested || wtoken.willBeHidden) {
                        continue;
                    }
                    haveGroup = true;
                    curGroup = wtoken.groupId;
                    lastOrientation = wtoken.requestedOrientation;
                } else if (curGroup != wtoken.groupId) {
                    // If we have hit a new application group, and the bottom
                    // of the previous group didn't explicitly say to use
                    // the orientation behind it, and the last app was
                    // full screen, then we'll stick with the
                    // user's orientation.
                    if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
                            && lastFullscreen) {
                        return lastOrientation;
                    }
                }
                int or = wtoken.requestedOrientation;
                // If this application is fullscreen, then just take whatever
                // orientation it has and ignores whatever is under it.
                lastFullscreen = wtoken.appFullscreen;
                if (lastFullscreen) {
                    return or;
                }
                // If this application has requested an explicit orientation,
                // then use it.
                if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
                        or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
                        or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
                        or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
                        or == ActivityInfo.SCREEN_ORIENTATION_USER) {
                    return or;
                }
            }
            return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    
public intgetOrientationFromWindowsLocked()

        int pos = mWindows.size() - 1;
        while (pos >= 0) {
            WindowState wtoken = (WindowState) mWindows.get(pos);
            pos--;
            if (wtoken.mAppToken != null) {
                // We hit an application window. so the orientation will be determined by the
                // app window. No point in continuing further.
                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
            }
            if (!wtoken.isVisibleLw()) {
                continue;
            }
            int req = wtoken.mAttrs.screenOrientation;
            if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
                    (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
                continue;
            } else {
                return req;
            }
        }
        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    
public intgetPendingAppTransition()

        return mNextAppTransition;
    
public intgetRotation()

        return mRotation;
    
public intgetScancodeState(int sw)

        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                "getScancodeState()")) {
            return -1;
        }
        return KeyInputQueue.getScancodeState(sw);
    
public intgetScancodeStateForDevice(int devid, int sw)

        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                "getScancodeStateForDevice()")) {
            return -1;
        }
        return KeyInputQueue.getScancodeState(devid, sw);
    
public intgetSwitchState(int sw)

        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                "getSwitchState()")) {
            return -1;
        }
        return KeyInputQueue.getSwitchState(sw);
    
public intgetSwitchStateForDevice(int devid, int sw)

        if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                "getSwitchStateForDevice()")) {
            return -1;
        }
        return KeyInputQueue.getSwitchState(devid, sw);
    
public voidgetWindowDisplayFrame(com.android.server.WindowManagerService$Session session, android.view.IWindow client, android.graphics.Rect outDisplayFrame)

        synchronized(mWindowMap) {
            WindowState win = windowForClientLocked(session, client);
            if (win == null) {
                outDisplayFrame.setEmpty();
                return;
            }
            outDisplayFrame.set(win.mDisplayFrame);
        }
    
public booleanhasKeys(int[] keycodes, boolean[] keyExists)

        return KeyInputQueue.hasKeys(keycodes, keyExists);
    
public booleaninKeyguardRestrictedInputMode()

        return mPolicy.inKeyguardRestrictedKeyInputMode();
    
public booleaninjectKeyEvent(android.view.KeyEvent ev, boolean sync)
Injects a keystroke event into the UI.

param
ev A motion event describing the keystroke action. (Be sure to use {@link SystemClock#uptimeMillis()} as the timebase.)
param
sync If true, wait for the event to be completed before returning to the caller.
return
Returns true if event was dispatched, false if it was dropped for any reason

        long downTime = ev.getDownTime();
        long eventTime = ev.getEventTime();

        int action = ev.getAction();
        int code = ev.getKeyCode();
        int repeatCount = ev.getRepeatCount();
        int metaState = ev.getMetaState();
        int deviceId = ev.getDeviceId();
        int scancode = ev.getScanCode();

        if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
        if (downTime == 0) downTime = eventTime;

        KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
                deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);

        boolean result = dispatchKey(newEvent, Binder.getCallingPid(), Binder.getCallingUid());
        if (sync) {
            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
        }
        return result;
    
public booleaninjectPointerEvent(android.view.MotionEvent ev, boolean sync)
Inject a pointer (touch) event into the UI.

param
ev A motion event describing the pointer (touch) action. (As noted in {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use {@link SystemClock#uptimeMillis()} as the timebase.)
param
sync If true, wait for the event to be completed before returning to the caller.
return
Returns true if event was dispatched, false if it was dropped for any reason

        boolean result = dispatchPointer(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
        if (sync) {
            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
        }
        return result;        
    
public booleaninjectTrackballEvent(android.view.MotionEvent ev, boolean sync)
Inject a trackball (navigation device) event into the UI.

param
ev A motion event describing the trackball action. (As noted in {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use {@link SystemClock#uptimeMillis()} as the timebase.)
param
sync If true, wait for the event to be completed before returning to the caller.
return
Returns true if event was dispatched, false if it was dropped for any reason

        boolean result = dispatchTrackball(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
        if (sync) {
            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
        }
        return result;
    
public booleaninputMethodClientHasFocus(com.android.internal.view.IInputMethodClient client)

        synchronized (mWindowMap) {
            // The focus for the client is the window immediately below
            // where we would place the input method window.
            int idx = findDesiredInputMethodWindowIndexLocked(false);
            WindowState imFocus;
            if (idx > 0) {
                imFocus = (WindowState)mWindows.get(idx-1);
                if (imFocus != null) {
                    if (imFocus.mSession.mClient != null &&
                            imFocus.mSession.mClient.asBinder() == client.asBinder()) {
                        return true;
                    }
                }
            }
        }
        return false;
    
public booleanisViewServerRunning()
Indicates whether the view server is running.

return
True if the server is running, false otherwise.
see
com.android.server.ViewServer

        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
            return false;
        }

        if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
            return false;
        }

        return mViewServer != null && mViewServer.isRunning();
    
private android.view.animation.AnimationloadAnimation(android.view.WindowManager.LayoutParams lp, int animAttr)

        int anim = 0;
        Context context = mContext;
        if (animAttr >= 0) {
            AttributeCache.Entry ent = getCachedAnimations(lp);
            if (ent != null) {
                context = ent.context;
                anim = ent.array.getResourceId(animAttr, 0);
            }
        }
        if (anim != 0) {
            return AnimationUtils.loadAnimation(context, anim);
        }
        return null;
    
voidlogWindowList(java.lang.String prefix)

        int N = mWindows.size();
        while (N > 0) {
            N--;
            Log.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
        }
    
public static com.android.server.WindowManagerServicemain(android.content.Context context, PowerManagerService pm, boolean haveInputMethods)

    
        
                
        WMThread thr = new WMThread(context, pm, haveInputMethods);
        thr.start();
        
        synchronized (thr) {
            while (thr.mService == null) {
                try {
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
        }
        
        return thr.mService;
    
public voidmonitor()

        synchronized (mWindowMap) { }
        synchronized (mKeyguardDisabled) { }
        synchronized (mKeyWaiter) { }
    
public voidmoveAppToken(int index, android.os.IBinder token)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "moveAppToken()")) {
            return;
        }

        synchronized(mWindowMap) {
            if (DEBUG_REORDER) Log.v(TAG, "Initial app tokens:");
            if (DEBUG_REORDER) dumpAppTokensLocked();
            final AppWindowToken wtoken = findAppWindowToken(token);
            if (wtoken == null || !mAppTokens.remove(wtoken)) {
                Log.w(TAG, "Attempting to reorder token that doesn't exist: "
                      + token + " (" + wtoken + ")");
                return;
            }
            mAppTokens.add(index, wtoken);
            if (DEBUG_REORDER) Log.v(TAG, "Moved " + token + " to " + index + ":");
            if (DEBUG_REORDER) dumpAppTokensLocked();
            
            final long origId = Binder.clearCallingIdentity();
            if (DEBUG_REORDER) Log.v(TAG, "Removing windows in " + token + ":");
            if (DEBUG_REORDER) dumpWindowsLocked();
            if (tmpRemoveAppWindowsLocked(wtoken)) {
                if (DEBUG_REORDER) Log.v(TAG, "Adding windows back in:");
                if (DEBUG_REORDER) dumpWindowsLocked();
                reAddAppWindowsLocked(findWindowOffsetLocked(index), wtoken);
                if (DEBUG_REORDER) Log.v(TAG, "Final window list:");
                if (DEBUG_REORDER) dumpWindowsLocked();
                updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
                mLayoutNeeded = true;
                performLayoutAndPlaceSurfacesLocked();
            }
            Binder.restoreCallingIdentity(origId);
        }
    
public voidmoveAppTokensToBottom(java.util.List tokens)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "moveAppTokensToBottom()")) {
            return;
        }

        final long origId = Binder.clearCallingIdentity();
        synchronized(mWindowMap) {
            removeAppTokensLocked(tokens);
            final int N = tokens.size();
            int pos = 0;
            for (int i=0; i<N; i++) {
                AppWindowToken wt = findAppWindowToken(tokens.get(i));
                if (wt != null) {
                    mAppTokens.add(pos, wt);
                    pos++;
                }
            }
            moveAppWindowsLocked(tokens, 0);
        }
        Binder.restoreCallingIdentity(origId);
    
public voidmoveAppTokensToTop(java.util.List tokens)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "moveAppTokensToTop()")) {
            return;
        }

        final long origId = Binder.clearCallingIdentity();
        synchronized(mWindowMap) {
            removeAppTokensLocked(tokens);
            final int N = tokens.size();
            for (int i=0; i<N; i++) {
                AppWindowToken wt = findAppWindowToken(tokens.get(i));
                if (wt != null) {
                    mAppTokens.add(wt);
                }
            }
            moveAppWindowsLocked(tokens, mAppTokens.size());
        }
        Binder.restoreCallingIdentity(origId);
    
private voidmoveAppWindowsLocked(java.util.List tokens, int tokenPos)

        // First remove all of the windows from the list.
        final int N = tokens.size();
        int i;
        for (i=0; i<N; i++) {
            WindowToken token = mTokenMap.get(tokens.get(i));
            if (token != null) {
                tmpRemoveAppWindowsLocked(token);
            }
        }

        // Where to start adding?
        int pos = findWindowOffsetLocked(tokenPos);

        // And now add them back at the correct place.
        for (i=0; i<N; i++) {
            WindowToken token = mTokenMap.get(tokens.get(i));
            if (token != null) {
                pos = reAddAppWindowsLocked(pos, token);
            }
        }

        updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
        mLayoutNeeded = true;
        performLayoutAndPlaceSurfacesLocked();

        //dump();
    
voidmoveInputMethodDialogsLocked(int pos)

        ArrayList<WindowState> dialogs = mInputMethodDialogs;
        
        final int N = dialogs.size();
        if (DEBUG_INPUT_METHOD) Log.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
        for (int i=0; i<N; i++) {
            pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
        }
        if (DEBUG_INPUT_METHOD) {
            Log.v(TAG, "Window list w/pos=" + pos);
            logWindowList("  ");
        }
        
        if (pos >= 0) {
            final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
            if (pos < mWindows.size()) {
                WindowState wp = (WindowState)mWindows.get(pos);
                if (wp == mInputMethodWindow) {
                    pos++;
                }
            }
            if (DEBUG_INPUT_METHOD) Log.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
            for (int i=0; i<N; i++) {
                WindowState win = dialogs.get(i);
                win.mTargetAppToken = targetAppToken;
                pos = reAddWindowLocked(pos, win);
            }
            if (DEBUG_INPUT_METHOD) {
                Log.v(TAG, "Final window list:");
                logWindowList("  ");
            }
            return;
        }
        for (int i=0; i<N; i++) {
            WindowState win = dialogs.get(i);
            win.mTargetAppToken = null;
            reAddWindowToListInOrderLocked(win);
            if (DEBUG_INPUT_METHOD) {
                Log.v(TAG, "No IM target, final list:");
                logWindowList("  ");
            }
        }
    
booleanmoveInputMethodWindowsIfNeededLocked(boolean needAssignLayers)

        final WindowState imWin = mInputMethodWindow;
        final int DN = mInputMethodDialogs.size();
        if (imWin == null && DN == 0) {
            return false;
        }
        
        int imPos = findDesiredInputMethodWindowIndexLocked(true);
        if (imPos >= 0) {
            // In this case, the input method windows are to be placed
            // immediately above the window they are targeting.
            
            // First check to see if the input method windows are already
            // located here, and contiguous.
            final int N = mWindows.size();
            WindowState firstImWin = imPos < N
                    ? (WindowState)mWindows.get(imPos) : null;
                    
            // Figure out the actual input method window that should be
            // at the bottom of their stack.
            WindowState baseImWin = imWin != null
                    ? imWin : mInputMethodDialogs.get(0);
            if (baseImWin.mChildWindows.size() > 0) {
                WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
                if (cw.mSubLayer < 0) baseImWin = cw;
            }
            
            if (firstImWin == baseImWin) {
                // The windows haven't moved...  but are they still contiguous?
                // First find the top IM window.
                int pos = imPos+1;
                while (pos < N) {
                    if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
                        break;
                    }
                    pos++;
                }
                pos++;
                // Now there should be no more input method windows above.
                while (pos < N) {
                    if (((WindowState)mWindows.get(pos)).mIsImWindow) {
                        break;
                    }
                    pos++;
                }
                if (pos >= N) {
                    // All is good!
                    return false;
                }
            }
            
            if (imWin != null) {
                if (DEBUG_INPUT_METHOD) {
                    Log.v(TAG, "Moving IM from " + imPos);
                    logWindowList("  ");
                }
                imPos = tmpRemoveWindowLocked(imPos, imWin);
                if (DEBUG_INPUT_METHOD) {
                    Log.v(TAG, "List after moving with new pos " + imPos + ":");
                    logWindowList("  ");
                }
                imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
                reAddWindowLocked(imPos, imWin);
                if (DEBUG_INPUT_METHOD) {
                    Log.v(TAG, "List after moving IM to " + imPos + ":");
                    logWindowList("  ");
                }
                if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
            } else {
                moveInputMethodDialogsLocked(imPos);
            }
            
        } else {
            // In this case, the input method windows go in a fixed layer,
            // because they aren't currently associated with a focus window.
            
            if (imWin != null) {
                if (DEBUG_INPUT_METHOD) Log.v(TAG, "Moving IM from " + imPos);
                tmpRemoveWindowLocked(0, imWin);
                imWin.mTargetAppToken = null;
                reAddWindowToListInOrderLocked(imWin);
                if (DEBUG_INPUT_METHOD) {
                    Log.v(TAG, "List with no IM target:");
                    logWindowList("  ");
                }
                if (DN > 0) moveInputMethodDialogsLocked(-1);;
            } else {
                moveInputMethodDialogsLocked(-1);;
            }
            
        }
        
        if (needAssignLayers) {
            assignLayersLocked();
        }
        
        return true;
    
public booleanonTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)

        try {
            return super.onTransact(code, data, reply, flags);
        } catch (RuntimeException e) {
            // The window manager only throws security exceptions, so let's
            // log all others.
            if (!(e instanceof SecurityException)) {
                Log.e(TAG, "Window Manager Crash", e);
            }
            throw e;
        }
    
public android.view.IWindowSessionopenSession(com.android.internal.view.IInputMethodClient client, com.android.internal.view.IInputContext inputContext)

        if (client == null) throw new IllegalArgumentException("null client");
        if (inputContext == null) throw new IllegalArgumentException("null inputContext");
        return new Session(client, inputContext);
    
public voidpauseKeyDispatching(android.os.IBinder _token)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "pauseKeyDispatching()")) {
            return;
        }

        synchronized (mWindowMap) {
            WindowToken token = mTokenMap.get(_token);
            if (token != null) {
                mKeyWaiter.pauseDispatchingLocked(token);
            }
        }
    
public voidperformEnableScreen()

        synchronized(mWindowMap) {
            if (mDisplayEnabled) {
                return;
            }
            if (!mSystemBooted) {
                return;
            }
            
            // Don't enable the screen until all existing windows
            // have been drawn.
            final int N = mWindows.size();
            for (int i=0; i<N; i++) {
                WindowState w = (WindowState)mWindows.get(i);
                if (w.isVisibleLw() && !w.isDisplayedLw()) {
                    return;
                }
            }
            
            mDisplayEnabled = true;
            if (false) {
                Log.i(TAG, "ENABLING SCREEN!");
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                this.dump(null, pw, null);
                Log.i(TAG, sw.toString());
            }
            try {
                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                if (surfaceFlinger != null) {
                    //Log.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                    Parcel data = Parcel.obtain();
                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
                                            data, null, 0);
                    data.recycle();
                }
            } catch (RemoteException ex) {
                Log.e(TAG, "Boot completed: SurfaceFlinger is dead!");
            }
        }
        
        mPolicy.enableScreenAfterBoot();
        
        // Make sure the last requested orientation has been applied.
        setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
                mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
    
private final voidperformLayoutAndPlaceSurfacesLocked()

        
        if (mInLayout) {
            if (Config.DEBUG) {
                throw new RuntimeException("Recursive call!");
            }
            Log.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout");
            return;
        }

        boolean recoveringMemory = false;
        if (mForceRemoves != null) {
            recoveringMemory = true;
            // Wait a little it for things to settle down, and off we go.
            for (int i=0; i<mForceRemoves.size(); i++) {
                WindowState ws = mForceRemoves.get(i);
                Log.i(TAG, "Force removing: " + ws);
                removeWindowInnerLocked(ws.mSession, ws);
            }
            mForceRemoves = null;
            Log.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) {
                }
            }
        }
        
        mInLayout = true;
        try {
            performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
            
            int i = mPendingRemove.size()-1;
            if (i >= 0) {
                while (i >= 0) {
                    WindowState w = mPendingRemove.get(i);
                    removeWindowInnerLocked(w.mSession, w);
                    i--;
                }
                mPendingRemove.clear();

                mInLayout = false;
                assignLayersLocked();
                mLayoutNeeded = true;
                performLayoutAndPlaceSurfacesLocked();

            } else {
                mInLayout = false;
                if (mLayoutNeeded) {
                    requestAnimationLocked(0);
                }
            }
        } catch (RuntimeException e) {
            mInLayout = false;
            Log.e(TAG, "Unhandled exception while layout out windows", e);
        }
    
private final voidperformLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory)

        final long currentTime = SystemClock.uptimeMillis();
        final int dw = mDisplay.getWidth();
        final int dh = mDisplay.getHeight();

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

        // FIRST LOOP: Perform a layout, if needed.
        
        performLayoutLockedInner();
        
        if (mFxSession == null) {
            mFxSession = new SurfaceSession();
        }
        
        if (SHOW_TRANSACTIONS) Log.i(TAG, ">>> OPEN TRANSACTION");

        // Initialize state of exiting tokens.
        for (i=mExitingTokens.size()-1; i>=0; i--) {
            mExitingTokens.get(i).hasVisible = false;
        }

        // Initialize state of exiting applications.
        for (i=mExitingAppTokens.size()-1; i>=0; i--) {
            mExitingAppTokens.get(i).hasVisible = false;
        }

        // SECOND LOOP: Execute animations and update visibility of windows.
        
        boolean orientationChangeComplete = true;
        Session holdScreen = null;
        float screenBrightness = -1;
        boolean focusDisplayed = false;
        boolean animating = false;

        Surface.openTransaction();
        try {
            boolean restart;

            do {
                final int transactionSequence = ++mTransactionSequence;

                // Update animations of all applications, including those
                // associated with exiting/removed apps
                boolean tokensAnimating = false;
                final int NAT = mAppTokens.size();
                for (i=0; i<NAT; i++) {
                    if (mAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
                        tokensAnimating = true;
                    }
                }
                final int NEAT = mExitingAppTokens.size();
                for (i=0; i<NEAT; i++) {
                    if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime, dw, dh)) {
                        tokensAnimating = true;
                    }
                }

                animating = tokensAnimating;
                restart = false;

                boolean tokenMayBeDrawn = false;

                mPolicy.beginAnimationLw(dw, dh);

                for (i=N-1; i>=0; i--) {
                    WindowState w = (WindowState)mWindows.get(i);

                    final WindowManager.LayoutParams attrs = w.mAttrs;

                    if (w.mSurface != null) {
                        // Execute animation.
                        w.commitFinishDrawingLocked(currentTime);
                        if (w.stepAnimationLocked(currentTime, dw, dh)) {
                            animating = true;
                            //w.dump("  ");
                        }

                        mPolicy.animatingWindowLw(w, attrs);
                    }

                    final AppWindowToken atoken = w.mAppToken;
                    if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
                        if (atoken.lastTransactionSequence != transactionSequence) {
                            atoken.lastTransactionSequence = transactionSequence;
                            atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
                            atoken.startingDisplayed = false;
                        }
                        if ((w.isOnScreen() || w.mAttrs.type
                                == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
                                && !w.mExiting && !w.mDestroying) {
                            if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
                                Log.v(TAG, "Eval win " + w + ": isDisplayed="
                                        + w.isDisplayedLw()
                                        + ", isAnimating=" + w.isAnimating());
                                if (!w.isDisplayedLw()) {
                                    Log.v(TAG, "Not displayed: s=" + w.mSurface
                                            + " pv=" + w.mPolicyVisibility
                                            + " dp=" + w.mDrawPending
                                            + " cdp=" + w.mCommitDrawPending
                                            + " ah=" + w.mAttachedHidden
                                            + " th=" + atoken.hiddenRequested
                                            + " a=" + w.mAnimating);
                                }
                            }
                            if (w != atoken.startingWindow) {
                                if (!atoken.freezingScreen || !w.mAppFreezing) {
                                    atoken.numInterestingWindows++;
                                    if (w.isDisplayedLw()) {
                                        atoken.numDrawnWindows++;
                                        if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Log.v(TAG,
                                                "tokenMayBeDrawn: " + atoken
                                                + " freezingScreen=" + atoken.freezingScreen
                                                + " mAppFreezing=" + w.mAppFreezing);
                                        tokenMayBeDrawn = true;
                                    }
                                }
                            } else if (w.isDisplayedLw()) {
                                atoken.startingDisplayed = true;
                            }
                        }
                    } else if (w.mReadyToShow) {
                        w.performShowLocked();
                    }
                }

                if (mPolicy.finishAnimationLw()) {
                    restart = true;
                }

                if (tokenMayBeDrawn) {
                    // See if any windows have been drawn, so they (and others
                    // associated with them) can now be shown.
                    final int NT = mTokenList.size();
                    for (i=0; i<NT; i++) {
                        AppWindowToken wtoken = mTokenList.get(i).appWindowToken;
                        if (wtoken == null) {
                            continue;
                        }
                        if (wtoken.freezingScreen) {
                            int numInteresting = wtoken.numInterestingWindows;
                            if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
                                if (DEBUG_VISIBILITY) Log.v(TAG,
                                        "allDrawn: " + wtoken
                                        + " interesting=" + numInteresting
                                        + " drawn=" + wtoken.numDrawnWindows);
                                wtoken.showAllWindowsLocked();
                                unsetAppFreezingScreenLocked(wtoken, false, true);
                                orientationChangeComplete = true;
                            }
                        } else if (!wtoken.allDrawn) {
                            int numInteresting = wtoken.numInterestingWindows;
                            if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
                                if (DEBUG_VISIBILITY) Log.v(TAG,
                                        "allDrawn: " + wtoken
                                        + " interesting=" + numInteresting
                                        + " drawn=" + wtoken.numDrawnWindows);
                                wtoken.allDrawn = true;
                                restart = true;

                                // We can now show all of the drawn windows!
                                if (!mOpeningApps.contains(wtoken)) {
                                    wtoken.showAllWindowsLocked();
                                }
                            }
                        }
                    }
                }

                // 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 (mAppTransitionReady) {
                    int NN = mOpeningApps.size();
                    boolean goodToGo = true;
                    if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
                            "Checking " + NN + " opening apps (frozen="
                            + mDisplayFrozen + " timeout="
                            + mAppTransitionTimeout + ")...");
                    if (!mDisplayFrozen && !mAppTransitionTimeout) {
                        // If the display isn't frozen, wait to do anything until
                        // all of the apps are ready.  Otherwise just go because
                        // we'll unfreeze the display when everyone is ready.
                        for (i=0; i<NN && goodToGo; i++) {
                            AppWindowToken wtoken = mOpeningApps.get(i);
                            if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
                                    "Check opening app" + wtoken + ": allDrawn="
                                    + wtoken.allDrawn + " startingDisplayed="
                                    + wtoken.startingDisplayed);
                            if (!wtoken.allDrawn && !wtoken.startingDisplayed
                                    && !wtoken.startingMoved) {
                                goodToGo = false;
                            }
                        }
                    }
                    if (goodToGo) {
                        if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "**** GOOD TO GO");
                        int transit = mNextAppTransition;
                        if (mSkipAppTransitionAnimation) {
                            transit = WindowManagerPolicy.TRANSIT_NONE;
                        }
                        mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
                        mAppTransitionReady = false;
                        mAppTransitionTimeout = false;
                        mStartingIconInTransition = false;
                        mSkipAppTransitionAnimation = false;

                        mH.removeMessages(H.APP_TRANSITION_TIMEOUT);

                        // We need to figure out which animation to use...
                        WindowManager.LayoutParams lp = findAnimations(mAppTokens,
                                mOpeningApps, mClosingApps);

                        NN = mOpeningApps.size();
                        for (i=0; i<NN; i++) {
                            AppWindowToken wtoken = mOpeningApps.get(i);
                            if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
                                    "Now opening app" + wtoken);
                            wtoken.reportedVisible = false;
                            wtoken.inPendingTransaction = false;
                            setTokenVisibilityLocked(wtoken, lp, true, transit, false);
                            wtoken.updateReportedVisibilityLocked();
                            wtoken.showAllWindowsLocked();
                        }
                        NN = mClosingApps.size();
                        for (i=0; i<NN; i++) {
                            AppWindowToken wtoken = mClosingApps.get(i);
                            if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
                                    "Now closing app" + wtoken);
                            wtoken.inPendingTransaction = false;
                            setTokenVisibilityLocked(wtoken, lp, false, transit, false);
                            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;
                        }

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

                        // This has changed the visibility of windows, so perform
                        // a new layout to get them all up-to-date.
                        mLayoutNeeded = true;
                        moveInputMethodWindowsIfNeededLocked(true);
                        performLayoutLockedInner();
                        updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);

                        restart = true;
                    }
                }
            } while (restart);

            // THIRD LOOP: Update the surfaces of all windows.

            final boolean someoneLosingFocus = mLosingFocus.size() != 0;

            boolean obscured = false;
            boolean blurring = false;
            boolean dimming = false;
            boolean covered = false;
            boolean syswin = false;

            for (i=N-1; i>=0; i--) {
                WindowState w = (WindowState)mWindows.get(i);

                boolean displayed = false;
                final WindowManager.LayoutParams attrs = w.mAttrs;
                final int attrFlags = attrs.flags;

                if (w.mSurface != null) {
                    w.computeShownFrameLocked();
                    if (localLOGV) Log.v(
                            TAG, "Placing surface #" + i + " " + w.mSurface
                            + ": new=" + w.mShownFrame + ", old="
                            + w.mLastShownFrame);

                    boolean resize;
                    int width, height;
                    if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
                        resize = w.mLastRequestedWidth != w.mRequestedWidth ||
                        w.mLastRequestedHeight != w.mRequestedHeight;
                        // for a scaled surface, we just want to use
                        // the requested size.
                        width  = w.mRequestedWidth;
                        height = w.mRequestedHeight;
                        w.mLastRequestedWidth = width;
                        w.mLastRequestedHeight = height;
                        w.mLastShownFrame.set(w.mShownFrame);
                        try {
                            w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
                        } catch (RuntimeException e) {
                            Log.w(TAG, "Error positioning surface in " + w, e);
                            if (!recoveringMemory) {
                                reclaimSomeSurfaceMemoryLocked(w, "position");
                            }
                        }
                    } else {
                        resize = !w.mLastShownFrame.equals(w.mShownFrame);
                        width = w.mShownFrame.width();
                        height = w.mShownFrame.height();
                        w.mLastShownFrame.set(w.mShownFrame);
                        if (resize) {
                            if (SHOW_TRANSACTIONS) Log.i(
                                    TAG, "  SURFACE " + w.mSurface + ": ("
                                    + w.mShownFrame.left + ","
                                    + w.mShownFrame.top + ") ("
                                    + w.mShownFrame.width() + "x"
                                    + w.mShownFrame.height() + ")");
                        }
                    }

                    if (resize) {
                        if (width < 1) width = 1;
                        if (height < 1) height = 1;
                        if (w.mSurface != null) {
                            try {
                                w.mSurface.setSize(width, height);
                                w.mSurface.setPosition(w.mShownFrame.left,
                                        w.mShownFrame.top);
                            } catch (RuntimeException e) {
                                // If something goes wrong with the surface (such
                                // as running out of memory), don't take down the
                                // entire system.
                                Log.e(TAG, "Failure updating surface of " + w
                                        + "size=(" + width + "x" + height
                                        + "), pos=(" + w.mShownFrame.left
                                        + "," + w.mShownFrame.top + ")", e);
                                if (!recoveringMemory) {
                                    reclaimSomeSurfaceMemoryLocked(w, "size");
                                }
                            }
                        }
                    }
                    if (!w.mAppFreezing) {
                        w.mContentInsetsChanged =
                            !w.mLastContentInsets.equals(w.mContentInsets);
                        w.mVisibleInsetsChanged =
                            !w.mLastVisibleInsets.equals(w.mVisibleInsets);
                        if (!w.mLastFrame.equals(w.mFrame) 
                                || w.mContentInsetsChanged
                                || w.mVisibleInsetsChanged) {
                            w.mLastFrame.set(w.mFrame);
                            w.mLastContentInsets.set(w.mContentInsets);
                            w.mLastVisibleInsets.set(w.mVisibleInsets);
                            // If the orientation is changing, then we need to
                            // hold off on unfreezing the display until this
                            // window has been redrawn; to do that, we need
                            // to go through the process of getting informed
                            // by the application when it has finished drawing.
                            if (w.mOrientationChanging) {
                                if (DEBUG_ORIENTATION) Log.v(TAG,
                                        "Orientation start waiting for draw in "
                                        + w + ", surface " + w.mSurface);
                                w.mDrawPending = true;
                                w.mCommitDrawPending = false;
                                w.mReadyToShow = false;
                                if (w.mAppToken != null) {
                                    w.mAppToken.allDrawn = false;
                                }
                            }
                            if (DEBUG_ORIENTATION) Log.v(TAG, 
                                    "Resizing window " + w + " to " + w.mFrame);
                            mResizingWindows.add(w);
                        } else if (w.mOrientationChanging) {
                            if (!w.mDrawPending && !w.mCommitDrawPending) {
                                if (DEBUG_ORIENTATION) Log.v(TAG,
                                        "Orientation not waiting for draw in "
                                        + w + ", surface " + w.mSurface);
                                w.mOrientationChanging = false;
                            }
                        }
                    }

                    if (w.mAttachedHidden) {
                        if (!w.mLastHidden) {
                            //dump();
                            w.mLastHidden = true;
                            if (SHOW_TRANSACTIONS) Log.i(
                                    TAG, "  SURFACE " + w.mSurface + ": HIDE (performLayout-attached)");
                            if (w.mSurface != null) {
                                try {
                                    w.mSurface.hide();
                                } catch (RuntimeException e) {
                                    Log.w(TAG, "Exception hiding surface in " + w);
                                }
                            }
                            mKeyWaiter.releasePendingPointerLocked(w.mSession);
                        }
                        // If we are waiting for this window to handle an
                        // orientation change, well, it is hidden, so
                        // doesn't really matter.  Note that this does
                        // introduce a potential glitch if the window
                        // becomes unhidden before it has drawn for the
                        // new orientation.
                        if (w.mOrientationChanging) {
                            w.mOrientationChanging = false;
                            if (DEBUG_ORIENTATION) Log.v(TAG,
                                    "Orientation change skips hidden " + w);
                        }
                    } else if (!w.isReadyForDisplay()) {
                        if (!w.mLastHidden) {
                            //dump();
                            w.mLastHidden = true;
                            if (SHOW_TRANSACTIONS) Log.i(
                                    TAG, "  SURFACE " + w.mSurface + ": HIDE (performLayout-ready)");
                            if (w.mSurface != null) {
                                try {
                                    w.mSurface.hide();
                                } catch (RuntimeException e) {
                                    Log.w(TAG, "Exception exception hiding surface in " + w);
                                }
                            }
                            mKeyWaiter.releasePendingPointerLocked(w.mSession);
                        }
                        // If we are waiting for this window to handle an
                        // orientation change, well, it is hidden, so
                        // doesn't really matter.  Note that this does
                        // introduce a potential glitch if the window
                        // becomes unhidden before it has drawn for the
                        // new orientation.
                        if (w.mOrientationChanging) {
                            w.mOrientationChanging = false;
                            if (DEBUG_ORIENTATION) Log.v(TAG,
                                    "Orientation change skips hidden " + w);
                        }
                    } else if (w.mLastLayer != w.mAnimLayer
                            || w.mLastAlpha != w.mShownAlpha
                            || w.mLastDsDx != w.mDsDx
                            || w.mLastDtDx != w.mDtDx
                            || w.mLastDsDy != w.mDsDy
                            || w.mLastDtDy != w.mDtDy
                            || w.mLastHScale != w.mHScale
                            || w.mLastVScale != w.mVScale
                            || w.mLastHidden) {
                        displayed = true;
                        w.mLastAlpha = w.mShownAlpha;
                        w.mLastLayer = w.mAnimLayer;
                        w.mLastDsDx = w.mDsDx;
                        w.mLastDtDx = w.mDtDx;
                        w.mLastDsDy = w.mDsDy;
                        w.mLastDtDy = w.mDtDy;
                        w.mLastHScale = w.mHScale;
                        w.mLastVScale = w.mVScale;
                        if (SHOW_TRANSACTIONS) Log.i(
                                TAG, "  SURFACE " + w.mSurface + ": alpha="
                                + w.mShownAlpha + " layer=" + w.mAnimLayer);
                        if (w.mSurface != null) {
                            try {
                                w.mSurface.setAlpha(w.mShownAlpha);
                                w.mSurface.setLayer(w.mAnimLayer);
                                w.mSurface.setMatrix(
                                        w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
                                        w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
                            } catch (RuntimeException e) {
                                Log.w(TAG, "Error updating surface in " + w, e);
                                if (!recoveringMemory) {
                                    reclaimSomeSurfaceMemoryLocked(w, "update");
                                }
                            }
                        }

                        if (w.mLastHidden && !w.mDrawPending
                                && !w.mCommitDrawPending
                                && !w.mReadyToShow) {
                            if (SHOW_TRANSACTIONS) Log.i(
                                    TAG, "  SURFACE " + w.mSurface + ": SHOW (performLayout)");
                            if (DEBUG_VISIBILITY) Log.v(TAG, "Showing " + w
                                    + " during relayout");
                            if (showSurfaceRobustlyLocked(w)) {
                                w.mHasDrawn = true;
                                w.mLastHidden = false;
                            } else {
                                w.mOrientationChanging = false;
                            }
                        }
                        if (w.mSurface != null) {
                            w.mToken.hasVisible = true;
                        }
                    } else {
                        displayed = true;
                    }

                    if (displayed) {
                        if (!covered) {
                            if (attrs.width == LayoutParams.FILL_PARENT
                                    && attrs.height == LayoutParams.FILL_PARENT) {
                                covered = true;
                            }
                        }
                        if (w.mOrientationChanging) {
                            if (w.mDrawPending || w.mCommitDrawPending) {
                                orientationChangeComplete = false;
                                if (DEBUG_ORIENTATION) Log.v(TAG,
                                        "Orientation continue waiting for draw in " + w);
                            } else {
                                w.mOrientationChanging = false;
                                if (DEBUG_ORIENTATION) Log.v(TAG,
                                        "Orientation change complete in " + w);
                            }
                        }
                        w.mToken.hasVisible = true;
                    }
                } else if (w.mOrientationChanging) {
                    if (DEBUG_ORIENTATION) Log.v(TAG,
                            "Orientation change skips hidden " + w);
                    w.mOrientationChanging = false;
                }

                final boolean canBeSeen = w.isDisplayedLw();

                if (someoneLosingFocus && w == mCurrentFocus && canBeSeen) {
                    focusDisplayed = true;
                }

                // Update effect.
                if (!obscured) {
                    if (w.mSurface != null) {
                        if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
                            holdScreen = w.mSession;
                        }
                        if (!syswin && w.mAttrs.screenBrightness >= 0
                                && screenBrightness < 0) {
                            screenBrightness = w.mAttrs.screenBrightness;
                        }
                        if (attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
                                || attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD
                                || attrs.type == WindowManager.LayoutParams.TYPE_SYSTEM_ERROR) {
                            syswin = true;
                        }
                    }
                    if (w.isFullscreenOpaque(dw, dh)) {
                        // This window completely covers everything behind it,
                        // so we want to leave all of them as unblurred (for
                        // performance reasons).
                        obscured = true;
                    } else if (canBeSeen && !obscured &&
                            (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
                        if (localLOGV) Log.v(TAG, "Win " + w
                                + ": blurring=" + blurring
                                + " obscured=" + obscured
                                + " displayed=" + displayed);
                        if ((attrFlags&FLAG_DIM_BEHIND) != 0) {
                            if (!dimming) {
                                //Log.i(TAG, "DIM BEHIND: " + w);
                                dimming = true;
                                mDimShown = true;
                                if (mDimSurface == null) {
                                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
                                            + mDimSurface + ": CREATE");
                                    try {
                                        mDimSurface = new Surface(mFxSession, 0, 
                                                -1, 16, 16,
                                                PixelFormat.OPAQUE,
                                                Surface.FX_SURFACE_DIM);
                                    } catch (Exception e) {
                                        Log.e(TAG, "Exception creating Dim surface", e);
                                    }
                                }
                                if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
                                        + mDimSurface + ": SHOW pos=(0,0) (" +
                                        dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
                                if (mDimSurface != null) {
                                    try {
                                        mDimSurface.setPosition(0, 0);
                                        mDimSurface.setSize(dw, dh);
                                        mDimSurface.show();
                                    } catch (RuntimeException e) {
                                        Log.w(TAG, "Failure showing dim surface", e);
                                    }
                                }
                            }
                            mDimSurface.setLayer(w.mAnimLayer-1);
                            final float target = w.mExiting ? 0 : attrs.dimAmount;
                            if (mDimTargetAlpha != target) {
                                // If the desired dim level has changed, then
                                // start an animation to it.
                                mLastDimAnimTime = currentTime;
                                long duration = (w.mAnimating && w.mAnimation != null)
                                        ? w.mAnimation.computeDurationHint()
                                        : DEFAULT_DIM_DURATION;
                                if (target > mDimTargetAlpha) {
                                    // This is happening behind the activity UI,
                                    // so we can make it run a little longer to
                                    // give a stronger impression without disrupting
                                    // the user.
                                    duration *= DIM_DURATION_MULTIPLIER;
                                }
                                if (duration < 1) {
                                    // Don't divide by zero
                                    duration = 1;
                                }
                                mDimTargetAlpha = target;
                                mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha)
                                        / duration;
                            }
                        }
                        if ((attrFlags&FLAG_BLUR_BEHIND) != 0) {
                            if (!blurring) {
                                //Log.i(TAG, "BLUR BEHIND: " + w);
                                blurring = true;
                                mBlurShown = true;
                                if (mBlurSurface == null) {
                                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  BLUR "
                                            + mBlurSurface + ": CREATE");
                                    try {
                                        mBlurSurface = new Surface(mFxSession, 0, 
                                                -1, 16, 16,
                                                PixelFormat.OPAQUE,
                                                Surface.FX_SURFACE_BLUR);
                                    } catch (Exception e) {
                                        Log.e(TAG, "Exception creating Blur surface", e);
                                    }
                                }
                                if (SHOW_TRANSACTIONS) Log.i(TAG, "  BLUR "
                                        + mBlurSurface + ": SHOW pos=(0,0) (" +
                                        dw + "x" + dh + "), layer=" + (w.mAnimLayer-1));
                                if (mBlurSurface != null) {
                                    mBlurSurface.setPosition(0, 0);
                                    mBlurSurface.setSize(dw, dh);
                                    try {
                                        mBlurSurface.show();
                                    } catch (RuntimeException e) {
                                        Log.w(TAG, "Failure showing blur surface", e);
                                    }
                                }
                            }
                            mBlurSurface.setLayer(w.mAnimLayer-2);
                        }
                    }
                }
            }

            if (!dimming && mDimShown) {
                // Time to hide the dim surface...  start fading.
                if (mDimTargetAlpha != 0) {
                    mLastDimAnimTime = currentTime;
                    mDimTargetAlpha = 0;
                    mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
                }
            }

            if (mDimShown && mLastDimAnimTime != 0) {
                mDimCurrentAlpha += mDimDeltaPerMs
                        * (currentTime-mLastDimAnimTime);
                boolean more = true;
                if (mDisplayFrozen) {
                    // If the display is frozen, there is no reason to animate.
                    more = false;
                } else if (mDimDeltaPerMs > 0) {
                    if (mDimCurrentAlpha > mDimTargetAlpha) {
                        more = false;
                    }
                } else if (mDimDeltaPerMs < 0) {
                    if (mDimCurrentAlpha < mDimTargetAlpha) {
                        more = false;
                    }
                } else {
                    more = false;
                }
                
                // Do we need to continue animating?
                if (more) {
                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
                            + mDimSurface + ": alpha=" + mDimCurrentAlpha);
                    mLastDimAnimTime = currentTime;
                    mDimSurface.setAlpha(mDimCurrentAlpha);
                    animating = true;
                } else {
                    mDimCurrentAlpha = mDimTargetAlpha;
                    mLastDimAnimTime = 0;
                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
                            + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
                    mDimSurface.setAlpha(mDimCurrentAlpha);
                    if (!dimming) {
                        if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM " + mDimSurface
                                + ": HIDE");
                        try {
                            mDimSurface.hide();
                        } catch (RuntimeException e) {
                            Log.w(TAG, "Illegal argument exception hiding dim surface");
                        }
                        mDimShown = false;
                    }
                }
            }
            
            if (!blurring && mBlurShown) {
                if (SHOW_TRANSACTIONS) Log.i(TAG, "  BLUR " + mBlurSurface
                        + ": HIDE");
                try {
                    mBlurSurface.hide();
                } catch (IllegalArgumentException e) {
                    Log.w(TAG, "Illegal argument exception hiding blur surface");
                }
                mBlurShown = false;
            }

            if (SHOW_TRANSACTIONS) Log.i(TAG, "<<< CLOSE TRANSACTION");
        } catch (RuntimeException e) {
            Log.e(TAG, "Unhandled exception in Window Manager", e);
        }

        Surface.closeTransaction();
        
        if (DEBUG_ORIENTATION && mDisplayFrozen) Log.v(TAG,
                "With display frozen, orientationChangeComplete="
                + orientationChangeComplete);
        if (orientationChangeComplete) {
            if (mWindowsFreezingScreen) {
                mWindowsFreezingScreen = false;
                mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
            }
            if (mAppsFreezingScreen == 0) {
                stopFreezingDisplayLocked();
            }
        }
        
        i = mResizingWindows.size();
        if (i > 0) {
            do {
                i--;
                WindowState win = mResizingWindows.get(i);
                try {
                    win.mClient.resized(win.mFrame.width(),
                            win.mFrame.height(), win.mLastContentInsets,
                            win.mLastVisibleInsets, win.mDrawPending);
                    win.mContentInsetsChanged = false;
                    win.mVisibleInsetsChanged = false;
                } catch (RemoteException e) {
                    win.mOrientationChanging = false;
                }
            } while (i > 0);
            mResizingWindows.clear();
        }
        
        // Destroy the surface of any windows that are no longer visible.
        i = mDestroySurface.size();
        if (i > 0) {
            do {
                i--;
                WindowState win = mDestroySurface.get(i);
                win.mDestroying = false;
                if (mInputMethodWindow == win) {
                    mInputMethodWindow = null;
                }
                win.destroySurfaceLocked();
            } while (i > 0);
            mDestroySurface.clear();
        }

        // Time to remove any exiting tokens?
        for (i=mExitingTokens.size()-1; i>=0; i--) {
            WindowToken token = mExitingTokens.get(i);
            if (!token.hasVisible) {
                mExitingTokens.remove(i);
            }
        }

        // Time to remove any exiting applications?
        for (i=mExitingAppTokens.size()-1; i>=0; i--) {
            AppWindowToken token = mExitingAppTokens.get(i);
            if (!token.hasVisible && !mClosingApps.contains(token)) {
                mAppTokens.remove(token);
                mExitingAppTokens.remove(i);
            }
        }

        if (focusDisplayed) {
            mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
        }
        if (animating) {
            requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
        }
        mQueue.setHoldScreenLocked(holdScreen != null);
        if (screenBrightness < 0 || screenBrightness > 1.0f) {
            mPowerManager.setScreenBrightnessOverride(-1);
        } else {
            mPowerManager.setScreenBrightnessOverride((int)
                    (screenBrightness * Power.BRIGHTNESS_ON));
        }
        if (holdScreen != mHoldingScreenOn) {
            mHoldingScreenOn = holdScreen;
            Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
            mH.sendMessage(m);
        }
    
private final voidperformLayoutLockedInner()

        final int dw = mDisplay.getWidth();
        final int dh = mDisplay.getHeight();

        final int N = mWindows.size();
        int repeats = 0;
        int i;

        // FIRST LOOP: Perform a layout, if needed.
        
        while (mLayoutNeeded) {
            mPolicy.beginLayoutLw(dw, dh);

            // First perform layout of any root windows (not attached
            // to another window).
            int topAttached = -1;
            for (i = N-1; i >= 0; i--) {
                WindowState win = (WindowState) mWindows.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 AppWindowToken atoken = win.mAppToken;
                final boolean gone = win.mViewVisibility == View.GONE
                        || !win.mRelayoutCalled
                        || win.mRootToken.hidden
                        || (atoken != null && atoken.hiddenRequested)
                        || !win.mPolicyVisibility
                        || win.mAttachedHidden
                        || win.mExiting || win.mDestroying;

                // 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) {
                    if (!win.mLayoutAttached) {
                        mPolicy.layoutWindowLw(win, win.mAttrs, null);
                    } else {
                        if (topAttached < 0) topAttached = i;
                    }
                }
            }
            
            // 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--) {
                WindowState win = (WindowState) mWindows.get(i);

                // 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 (win.mLayoutAttached) {
                    if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
                            || !win.mHaveFrame) {
                        mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
                    }
                }
            }

            if (!mPolicy.finishLayoutLw()) {
                mLayoutNeeded = false;
            } else if (repeats > 2) {
                Log.w(TAG, "Layout repeat aborted after too many iterations");
                mLayoutNeeded = false;
            } else {
                repeats++;
            }
        }
    
private voidplaceWindowAfter(java.lang.Object pos, com.android.server.WindowManagerService$WindowState window)

        final int i = mWindows.indexOf(pos);
        if (localLOGV || DEBUG_FOCUS) Log.v(
            TAG, "Adding window " + window + " at "
            + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
        mWindows.add(i+1, window);
    
private voidplaceWindowBefore(java.lang.Object pos, com.android.server.WindowManagerService$WindowState window)

        final int i = mWindows.indexOf(pos);
        if (localLOGV || DEBUG_FOCUS) Log.v(
            TAG, "Adding window " + window + " at "
            + i + " of " + mWindows.size() + " (before " + pos + ")");
        mWindows.add(i, window);
    
public voidprepareAppTransition(int transit)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "prepareAppTransition()")) {
            return;
        }
        
        synchronized(mWindowMap) {
            if (DEBUG_APP_TRANSITIONS) Log.v(
                    TAG, "Prepare app transition: transit=" + transit
                    + " mNextAppTransition=" + mNextAppTransition);
            if (!mDisplayFrozen) {
                if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
                    mNextAppTransition = transit;
                }
                mAppTransitionReady = false;
                mAppTransitionTimeout = false;
                mStartingIconInTransition = false;
                mSkipAppTransitionAnimation = false;
                mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
                mH.sendMessageDelayed(mH.obtainMessage(H.APP_TRANSITION_TIMEOUT),
                        5000);
            }
        }
    
private final intreAddAppWindowsLocked(int index, com.android.server.WindowManagerService$WindowToken token)

        final int NW = token.windows.size();
        for (int i=0; i<NW; i++) {
            index = reAddWindowLocked(index, token.windows.get(i));
        }
        return index;
    
private final intreAddWindowLocked(int index, com.android.server.WindowManagerService$WindowState win)

        final int NCW = win.mChildWindows.size();
        boolean added = false;
        for (int j=0; j<NCW; j++) {
            WindowState cwin = (WindowState)win.mChildWindows.get(j);
            if (!added && cwin.mSubLayer >= 0) {
                mWindows.add(index, win);
                index++;
                added = true;
            }
            mWindows.add(index, cwin);
            index++;
        }
        if (!added) {
            mWindows.add(index, win);
            index++;
        }
        return index;
    
private voidreAddWindowToListInOrderLocked(com.android.server.WindowManagerService$WindowState win)

        addWindowToListInOrderLocked(win, false);
        // This is a hack to get all of the child windows added as well
        // at the right position.  Child windows should be rare and
        // this case should be rare, so it shouldn't be that big a deal.
        int wpos = mWindows.indexOf(win);
        if (wpos >= 0) {
            mWindows.remove(wpos);
            reAddWindowLocked(wpos, win);
        }
    
voidreclaimSomeSurfaceMemoryLocked(com.android.server.WindowManagerService$WindowState win, java.lang.String operation)

        final Surface surface = win.mSurface;
        
        EventLog.writeEvent(LOG_WM_NO_SURFACE_MEMORY, win.toString(),
                win.mSession.mPid, operation);
        
        if (mForceRemoves == null) {
            mForceRemoves = new ArrayList<WindowState>();
        }
        
        long callingIdentity = Binder.clearCallingIdentity();
        try {
            // There was some problem...   first, do a sanity check of the
            // window list to make sure we haven't left any dangling surfaces
            // around.
            int N = mWindows.size();
            boolean leakedSurface = false;
            Log.i(TAG, "Out of memory for surface!  Looking for leaks...");
            for (int i=0; i<N; i++) {
                WindowState ws = (WindowState)mWindows.get(i);
                if (ws.mSurface != null) {
                    if (!mSessions.contains(ws.mSession)) {
                        Log.w(TAG, "LEAKED SURFACE (session doesn't exist): "
                                + ws + " surface=" + ws.mSurface
                                + " token=" + win.mToken
                                + " pid=" + ws.mSession.mPid
                                + " uid=" + ws.mSession.mUid);
                        ws.mSurface.clear();
                        ws.mSurface = null;
                        mForceRemoves.add(ws);
                        i--;
                        N--;
                        leakedSurface = true;
                    } else if (win.mAppToken != null && win.mAppToken.clientHidden) {
                        Log.w(TAG, "LEAKED SURFACE (app token hidden): "
                                + ws + " surface=" + ws.mSurface
                                + " token=" + win.mAppToken);
                        ws.mSurface.clear();
                        ws.mSurface = null;
                        leakedSurface = true;
                    }
                }
            }
            
            boolean killedApps = false;
            if (!leakedSurface) {
                Log.w(TAG, "No leaked surfaces; killing applicatons!");
                SparseIntArray pidCandidates = new SparseIntArray();
                for (int i=0; i<N; i++) {
                    WindowState ws = (WindowState)mWindows.get(i);
                    if (ws.mSurface != null) {
                        pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
                    }
                }
                if (pidCandidates.size() > 0) {
                    int[] pids = new int[pidCandidates.size()];
                    for (int i=0; i<pids.length; i++) {
                        pids[i] = pidCandidates.keyAt(i);
                    }
                    try {
                        if (mActivityManager.killPidsForMemory(pids)) {
                            killedApps = true;
                        }
                    } catch (RemoteException e) {
                    }
                }
            }
            
            if (leakedSurface || killedApps) {
                // We managed to reclaim some memory, so get rid of the trouble
                // surface and ask the app to request another one.
                Log.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
                if (surface != null) {
                    surface.clear();
                    win.mSurface = null;
                }
                
                try {
                    win.mClient.dispatchGetNewSurface();
                } catch (RemoteException e) {
                }
            }
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
    
public voidreenableKeyguard(android.os.IBinder token)

        if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
            != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
        }
        synchronized (mKeyguardDisabled) {
            mKeyguardDisabled.release(token);

            if (!mKeyguardDisabled.isAcquired()) {
                // if we are the last one to reenable the keyguard wait until
                // we have actaully finished reenabling until returning
                mWaitingUntilKeyguardReenabled = true;
                while (mWaitingUntilKeyguardReenabled) {
                    try {
                        mKeyguardDisabled.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    
public intrelayoutWindow(com.android.server.WindowManagerService$Session session, android.view.IWindow client, android.view.WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, boolean insetsPending, android.graphics.Rect outFrame, android.graphics.Rect outContentInsets, android.graphics.Rect outVisibleInsets, android.view.Surface outSurface)

        boolean displayed = false;
        boolean inTouchMode;
        Configuration newConfig = null;
        long origId = Binder.clearCallingIdentity();
        
        synchronized(mWindowMap) {
            WindowState win = windowForClientLocked(session, client);
            if (win == null) {
                return 0;
            }
            win.mRequestedWidth = requestedWidth;
            win.mRequestedHeight = requestedHeight;

            if (attrs != null) {
                mPolicy.adjustWindowParamsLw(attrs);
            }
            
            int attrChanges = 0;
            int flagChanges = 0;
            if (attrs != null) {
                flagChanges = win.mAttrs.flags ^= attrs.flags;
                attrChanges = win.mAttrs.copyFrom(attrs);
            }

            if (localLOGV) Log.v(
                TAG, "Relayout given client " + client.asBinder()
                + " (" + win.mAttrs.getTitle() + ")");


            if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
                win.mAlpha = attrs.alpha;
            }

            final boolean scaledWindow =
                ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);

            if (scaledWindow) {
                // requested{Width|Height} Surface's physical size
                // attrs.{width|height} Size on screen
                win.mHScale = (attrs.width  != requestedWidth)  ?
                        (attrs.width  / (float)requestedWidth) : 1.0f;
                win.mVScale = (attrs.height != requestedHeight) ?
                        (attrs.height / (float)requestedHeight) : 1.0f;
            }

            boolean imMayMove = (flagChanges&(
                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
            
            boolean focusMayChange = win.mViewVisibility != viewVisibility
                    || ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
                    || (!win.mRelayoutCalled);
            
            win.mRelayoutCalled = true;
            final int oldVisibility = win.mViewVisibility;
            win.mViewVisibility = viewVisibility;
            if (viewVisibility == View.VISIBLE &&
                    (win.mAppToken == null || !win.mAppToken.clientHidden)) {
                displayed = !win.isVisibleLw();
                if (win.mExiting) {
                    win.mExiting = false;
                    win.mAnimation = null;
                }
                if (win.mDestroying) {
                    win.mDestroying = false;
                    mDestroySurface.remove(win);
                }
                if (oldVisibility == View.GONE) {
                    win.mEnterAnimationPending = true;
                }
                if (displayed && win.mSurface != null && !win.mDrawPending
                        && !win.mCommitDrawPending && !mDisplayFrozen) {
                    applyEnterAnimationLocked(win);
                }
                if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
                    // To change the format, we need to re-build the surface.
                    win.destroySurfaceLocked();
                    displayed = true;
                }
                try {
                    Surface surface = win.createSurfaceLocked();
                    if (surface != null) {
                        outSurface.copyFrom(surface);
                    } else {
                        outSurface.clear();
                    }
                } catch (Exception e) {
                    Log.w(TAG, "Exception thrown when creating surface for client "
                         + client + " (" + win.mAttrs.getTitle() + ")",
                         e);
                    Binder.restoreCallingIdentity(origId);
                    return 0;
                }
                if (displayed) {
                    focusMayChange = true;
                }
                if (win.mAttrs.type == TYPE_INPUT_METHOD
                        && mInputMethodWindow == null) {
                    mInputMethodWindow = win;
                    imMayMove = true;
                }
            } else {
                win.mEnterAnimationPending = false;
                if (win.mSurface != null) {
                    // If we are not currently running the exit animation, we
                    // need to see about starting one.
                    if (!win.mExiting) {
                        // Try starting an animation; if there isn't one, we
                        // can destroy the surface right away.
                        int transit = WindowManagerPolicy.TRANSIT_EXIT;
                        if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
                            transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
                        }
                        if (win.isWinVisibleLw() &&
                              applyAnimationLocked(win, transit, false)) {
                            win.mExiting = true;
                            mKeyWaiter.finishedKey(session, client, true,
                                    KeyWaiter.RETURN_NOTHING);
                        } else if (win.isAnimating()) {
                            // Currently in a hide animation... turn this into
                            // an exit.
                            win.mExiting = true;
                        } else {
                            if (mInputMethodWindow == win) {
                                mInputMethodWindow = null;
                            }
                            win.destroySurfaceLocked();
                        }
                    }
                }
                outSurface.clear();
            }

            if (focusMayChange) {
                //System.out.println("Focus may change: " + win.mAttrs.getTitle());
                if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
                    imMayMove = false;
                }
                //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
            }
            
            // updateFocusedWindowLocked() already assigned layers so we only need to
            // reassign them at this point if the IM window state gets shuffled
            boolean assignLayers = false;
            
            if (imMayMove) {
                if (moveInputMethodWindowsIfNeededLocked(false)) {
                    assignLayers = true;
                }
            }
                
            mLayoutNeeded = true;
            win.mGivenInsetsPending = insetsPending;
            if (assignLayers) {
                assignLayersLocked();
            }
            newConfig = updateOrientationFromAppTokensLocked(null, null);
            performLayoutAndPlaceSurfacesLocked();
            if (win.mAppToken != null) {
                win.mAppToken.updateReportedVisibilityLocked();
            }
            outFrame.set(win.mFrame);
            outContentInsets.set(win.mContentInsets);
            outVisibleInsets.set(win.mVisibleInsets);
            if (localLOGV) Log.v(
                TAG, "Relayout given client " + client.asBinder()
                + ", requestedWidth=" + requestedWidth 
                + ", requestedHeight=" + requestedHeight
                + ", viewVisibility=" + viewVisibility
                + "\nRelayout returning frame=" + outFrame
                + ", surface=" + outSurface);

            if (localLOGV || DEBUG_FOCUS) Log.v(
                TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);

            inTouchMode = mInTouchMode;
        }

        if (newConfig != null) {
            sendNewConfiguration();
        }
        
        Binder.restoreCallingIdentity(origId);
        
        return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
                | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
    
public voidremoveAppToken(android.os.IBinder token)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "removeAppToken()")) {
            return;
        }

        AppWindowToken wtoken = null;
        AppWindowToken startingToken = null;
        boolean delayed = false;

        final long origId = Binder.clearCallingIdentity();
        synchronized(mWindowMap) {
            WindowToken basewtoken = mTokenMap.remove(token);
            mTokenList.remove(basewtoken);
            if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
                if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "Removing app token: " + wtoken);
                delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_NONE, true);
                wtoken.inPendingTransaction = false;
                mOpeningApps.remove(wtoken);
                if (mClosingApps.contains(wtoken)) {
                    delayed = true;
                } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
                    mClosingApps.add(wtoken);
                    delayed = true;
                }
                if (DEBUG_APP_TRANSITIONS) Log.v(
                        TAG, "Removing app " + wtoken + " delayed=" + delayed
                        + " animation=" + wtoken.animation
                        + " animating=" + wtoken.animating);
                if (delayed) {
                    // set the token aside because it has an active animation to be finished
                    mExitingAppTokens.add(wtoken);
                }
                mAppTokens.remove(wtoken);
                wtoken.removed = true;
                if (wtoken.startingData != null) {
                    startingToken = wtoken;
                }
                unsetAppFreezingScreenLocked(wtoken, true, true);
                if (mFocusedApp == wtoken) {
                    if (DEBUG_FOCUS) Log.v(TAG, "Removing focused app token:" + wtoken);
                    mFocusedApp = null;
                    updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
                    mKeyWaiter.tickle();
                }
            } else {
                Log.w(TAG, "Attempted to remove non-existing app token: " + token);
            }
            
            if (!delayed && wtoken != null) {
                wtoken.updateReportedVisibilityLocked();
            }
        }
        Binder.restoreCallingIdentity(origId);

        if (startingToken != null) {
            if (DEBUG_STARTING_WINDOW) Log.v(TAG, "Schedule remove starting "
                    + startingToken + ": app token removed");
            Message m = mH.obtainMessage(H.REMOVE_STARTING, startingToken);
            mH.sendMessage(m);
        }
    
private voidremoveAppTokensLocked(java.util.List tokens)

        // XXX This should be done more efficiently!
        // (take advantage of the fact that both lists should be
        // ordered in the same way.)
        int N = tokens.size();
        for (int i=0; i<N; i++) {
            IBinder token = tokens.get(i);
            final AppWindowToken wtoken = findAppWindowToken(token);
            if (!mAppTokens.remove(wtoken)) {
                Log.w(TAG, "Attempting to reorder token that doesn't exist: "
                      + token + " (" + wtoken + ")");
                i--;
                N--;
            }
        }
    
public voidremoveWindow(com.android.server.WindowManagerService$Session session, android.view.IWindow client)

        synchronized(mWindowMap) {
            WindowState win = windowForClientLocked(session, client);
            if (win == null) {
                return;
            }
            removeWindowLocked(session, win);
        }
    
private voidremoveWindowInnerLocked(com.android.server.WindowManagerService$Session session, com.android.server.WindowManagerService$WindowState win)

        mKeyWaiter.releasePendingPointerLocked(win.mSession);
        mKeyWaiter.releasePendingTrackballLocked(win.mSession);
        
        win.mRemoved = true;
        
        if (mInputMethodTarget == win) {
            moveInputMethodWindowsIfNeededLocked(false);
        }
        
        mPolicy.removeWindowLw(win);
        win.removeLocked();

        mWindowMap.remove(win.mClient.asBinder());
        mWindows.remove(win);

        if (mInputMethodWindow == win) {
            mInputMethodWindow = null;
        } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
            mInputMethodDialogs.remove(win);
        }
        
        final WindowToken token = win.mToken;
        final AppWindowToken atoken = win.mAppToken;
        token.windows.remove(win);
        if (atoken != null) {
            atoken.allAppWindows.remove(win);
        }
        if (localLOGV) Log.v(
                TAG, "**** Removing window " + win + ": count="
                + token.windows.size());
        if (token.windows.size() == 0) {
            if (!token.explicit) {
                mTokenMap.remove(token.token);
                mTokenList.remove(token);
            } else if (atoken != null) {
                atoken.firstWindowDrawn = false;
            }
        }

        if (atoken != null) {
            if (atoken.startingWindow == win) {
                atoken.startingWindow = null;
            } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
                // If this is the last window and we had requested a starting
                // transition window, well there is no point now.
                atoken.startingData = null;
            } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
                // If this is the last window except for a starting transition
                // window, we need to get rid of the starting transition.
                if (DEBUG_STARTING_WINDOW) {
                    Log.v(TAG, "Schedule remove starting " + token
                            + ": no more real windows");
                }
                Message m = mH.obtainMessage(H.REMOVE_STARTING, atoken);
                mH.sendMessage(m);
            }
        }
        
        if (!mInLayout) {
            assignLayersLocked();
            mLayoutNeeded = true;
            performLayoutAndPlaceSurfacesLocked();
            if (win.mAppToken != null) {
                win.mAppToken.updateReportedVisibilityLocked();
            }
        }
    
public voidremoveWindowLocked(com.android.server.WindowManagerService$Session session, com.android.server.WindowManagerService$WindowState win)


        if (localLOGV || DEBUG_FOCUS) Log.v(
            TAG, "Remove " + win + " client="
            + Integer.toHexString(System.identityHashCode(
                win.mClient.asBinder()))
            + ", surface=" + win.mSurface);

        final long origId = Binder.clearCallingIdentity();
        
        if (DEBUG_APP_TRANSITIONS) Log.v(
                TAG, "Remove " + win + ": mSurface=" + win.mSurface
                + " mExiting=" + win.mExiting
                + " isAnimating=" + win.isAnimating()
                + " app-animation="
                + (win.mAppToken != null ? win.mAppToken.animation : null)
                + " inPendingTransaction="
                + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
                + " mDisplayFrozen=" + mDisplayFrozen);
        // Visibility of the removed window. Will be used later to update orientation later on.
        boolean wasVisible = false;
        // First, see if we need to run an animation.  If we do, we have
        // to hold off on removing the window until the animation is done.
        // If the display is frozen, just remove immediately, since the
        // animation wouldn't be seen.
        if (win.mSurface != null && !mDisplayFrozen) {
            // If we are not currently running the exit animation, we
            // need to see about starting one.
            if (wasVisible=win.isWinVisibleLw()) {
                
                int transit = WindowManagerPolicy.TRANSIT_EXIT;
                if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
                    transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
                }
                // Try starting an animation.
                if (applyAnimationLocked(win, transit, false)) {
                    win.mExiting = true;
                }
            }
            if (win.mExiting || win.isAnimating()) {
                // The exit animation is running... wait for it!
                //Log.i(TAG, "*** Running exit animation...");
                win.mExiting = true;
                win.mRemoveOnExit = true;
                mLayoutNeeded = true;
                updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
                performLayoutAndPlaceSurfacesLocked();
                if (win.mAppToken != null) {
                    win.mAppToken.updateReportedVisibilityLocked();
                }
                //dump();
                Binder.restoreCallingIdentity(origId);
                return;
            }
        }

        removeWindowInnerLocked(session, win);
        // Removing a visible window will effect the computed orientation
        // So just update orientation if needed.
        if (wasVisible && computeForcedAppOrientationLocked()
                != mForcedAppOrientation) {
            mH.sendMessage(mH.obtainMessage(H.COMPUTE_AND_SEND_NEW_CONFIGURATION));
        }
        updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
        Binder.restoreCallingIdentity(origId);
    
public voidremoveWindowToken(android.os.IBinder token)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "removeWindowToken()")) {
            return;
        }

        final long origId = Binder.clearCallingIdentity();
        synchronized(mWindowMap) {
            WindowToken wtoken = mTokenMap.remove(token);
            mTokenList.remove(wtoken);
            if (wtoken != null) {
                boolean delayed = false;
                if (!wtoken.hidden) {
                    wtoken.hidden = true;
                    
                    final int N = wtoken.windows.size();
                    boolean changed = false;
                    
                    for (int i=0; i<N; i++) {
                        WindowState win = wtoken.windows.get(i);

                        if (win.isAnimating()) {
                            delayed = true;
                        }
                        
                        if (win.isVisibleNow()) {
                            applyAnimationLocked(win,
                                    WindowManagerPolicy.TRANSIT_EXIT, false);
                            mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
                                    KeyWaiter.RETURN_NOTHING);
                            changed = true;
                        }
                    }

                    if (changed) {
                        mLayoutNeeded = true;
                        performLayoutAndPlaceSurfacesLocked();
                        updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
                    }
                    
                    if (delayed) {
                        mExitingTokens.add(wtoken);
                    }
                }
                
            } else {
                Log.w(TAG, "Attempted to remove non-existing token: " + token);
            }
        }
        Binder.restoreCallingIdentity(origId);
    
voidrequestAnimationLocked(long delay)

        if (!mAnimationPending) {
            mAnimationPending = true;
            mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
        }
    
public voidresumeKeyDispatching(android.os.IBinder _token)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "resumeKeyDispatching()")) {
            return;
        }

        synchronized (mWindowMap) {
            WindowToken token = mTokenMap.get(_token);
            if (token != null) {
                mKeyWaiter.resumeDispatchingLocked(token);
            }
        }
    
voidsendNewConfiguration()

        try {
            mActivityManager.updateConfiguration(null);
        } catch (RemoteException e) {
        }
    
public voidsetAnimationScale(int which, float scale)

        if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
                "setAnimationScale()")) {
            return;
        }

        if (scale < 0) scale = 0;
        else if (scale > 20) scale = 20;
        scale = Math.abs(scale);
        switch (which) {
            case 0: mWindowAnimationScale = fixScale(scale); break;
            case 1: mTransitionAnimationScale = fixScale(scale); break;
        }
        
        // Persist setting
        mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
    
public voidsetAnimationScales(float[] scales)

        if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
                "setAnimationScale()")) {
            return;
        }

        if (scales != null) {
            if (scales.length >= 1) {
                mWindowAnimationScale = fixScale(scales[0]);
            }
            if (scales.length >= 2) {
                mTransitionAnimationScale = fixScale(scales[1]);
            }
        }
        
        // Persist setting
        mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
    
public voidsetAppGroupId(android.os.IBinder token, int groupId)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setAppStartingIcon()")) {
            return;
        }

        synchronized(mWindowMap) {
            AppWindowToken wtoken = findAppWindowToken(token);
            if (wtoken == null) {
                Log.w(TAG, "Attempted to set group id of non-existing app token: " + token);
                return;
            }
            wtoken.groupId = groupId;
        }
    
public voidsetAppOrientation(android.view.IApplicationToken token, int requestedOrientation)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setAppOrientation()")) {
            return;
        }
        
        synchronized(mWindowMap) {
            AppWindowToken wtoken = findAppWindowToken(token.asBinder());
            if (wtoken == null) {
                Log.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
                return;
            }
            
            wtoken.requestedOrientation = requestedOrientation;
        }
    
public voidsetAppStartingWindow(android.os.IBinder token, java.lang.String pkg, int theme, java.lang.CharSequence nonLocalizedLabel, int labelRes, int icon, android.os.IBinder transferFrom, boolean createIfNeeded)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setAppStartingIcon()")) {
            return;
        }

        synchronized(mWindowMap) {
            if (DEBUG_STARTING_WINDOW) Log.v(
                    TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
                    + " transferFrom=" + transferFrom);
            
            AppWindowToken wtoken = findAppWindowToken(token);
            if (wtoken == null) {
                Log.w(TAG, "Attempted to set icon of non-existing app token: " + token);
                return;
            }

            // If the display is frozen, we won't do anything until the
            // actual window is displayed so there is no reason to put in
            // the starting window.
            if (mDisplayFrozen) {
                return;
            }
            
            if (wtoken.startingData != null) {
                return;
            }
            
            if (transferFrom != null) {
                AppWindowToken ttoken = findAppWindowToken(transferFrom);
                if (ttoken != null) {
                    WindowState startingWindow = ttoken.startingWindow;
                    if (startingWindow != null) {
                        if (mStartingIconInTransition) {
                            // In this case, the starting icon has already
                            // been displayed, so start letting windows get
                            // shown immediately without any more transitions.
                            mSkipAppTransitionAnimation = true;
                        }
                        if (DEBUG_STARTING_WINDOW) Log.v(TAG,
                                "Moving existing starting from " + ttoken
                                + " to " + wtoken);
                        final long origId = Binder.clearCallingIdentity();
                        
                        // Transfer the starting window over to the new
                        // token.
                        wtoken.startingData = ttoken.startingData;
                        wtoken.startingView = ttoken.startingView;
                        wtoken.startingWindow = startingWindow;
                        ttoken.startingData = null;
                        ttoken.startingView = null;
                        ttoken.startingWindow = null;
                        ttoken.startingMoved = true;
                        startingWindow.mToken = wtoken;
                        startingWindow.mRootToken = wtoken;
                        startingWindow.mAppToken = wtoken;
                        mWindows.remove(startingWindow);
                        ttoken.windows.remove(startingWindow);
                        ttoken.allAppWindows.remove(startingWindow);
                        addWindowToListInOrderLocked(startingWindow, true);
                        wtoken.allAppWindows.add(startingWindow);
                        
                        // Propagate other interesting state between the
                        // tokens.  If the old token is displayed, we should
                        // immediately force the new one to be displayed.  If
                        // it is animating, we need to move that animation to
                        // the new one.
                        if (ttoken.allDrawn) {
                            wtoken.allDrawn = true;
                        }
                        if (ttoken.firstWindowDrawn) {
                            wtoken.firstWindowDrawn = true;
                        }
                        if (!ttoken.hidden) {
                            wtoken.hidden = false;
                            wtoken.hiddenRequested = false;
                            wtoken.willBeHidden = false;
                        }
                        if (wtoken.clientHidden != ttoken.clientHidden) {
                            wtoken.clientHidden = ttoken.clientHidden;
                            wtoken.sendAppVisibilityToClients();
                        }
                        if (ttoken.animation != null) {
                            wtoken.animation = ttoken.animation;
                            wtoken.animating = ttoken.animating;
                            wtoken.animLayerAdjustment = ttoken.animLayerAdjustment;
                            ttoken.animation = null;
                            ttoken.animLayerAdjustment = 0;
                            wtoken.updateLayers();
                            ttoken.updateLayers();
                        }
                        
                        updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
                        mLayoutNeeded = true;
                        performLayoutAndPlaceSurfacesLocked();
                        Binder.restoreCallingIdentity(origId);
                        return;
                    } else if (ttoken.startingData != null) {
                        // The previous app was getting ready to show a
                        // starting window, but hasn't yet done so.  Steal it!
                        if (DEBUG_STARTING_WINDOW) Log.v(TAG,
                                "Moving pending starting from " + ttoken
                                + " to " + wtoken);
                        wtoken.startingData = ttoken.startingData;
                        ttoken.startingData = null;
                        ttoken.startingMoved = true;
                        Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
                        // Note: we really want to do sendMessageAtFrontOfQueue() because we
                        // want to process the message ASAP, before any other queued
                        // messages.
                        mH.sendMessageAtFrontOfQueue(m);
                        return;
                    }
                }
            }

            // There is no existing starting window, and the caller doesn't
            // want us to create one, so that's it!
            if (!createIfNeeded) {
                return;
            }
            
            mStartingIconInTransition = true;
            wtoken.startingData = new StartingData(
                    pkg, theme, nonLocalizedLabel,
                    labelRes, icon);
            Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
            // Note: we really want to do sendMessageAtFrontOfQueue() because we
            // want to process the message ASAP, before any other queued
            // messages.
            mH.sendMessageAtFrontOfQueue(m);
        }
    
public voidsetAppVisibility(android.os.IBinder token, boolean visible)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setAppVisibility()")) {
            return;
        }

        AppWindowToken wtoken;

        synchronized(mWindowMap) {
            wtoken = findAppWindowToken(token);
            if (wtoken == null) {
                Log.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
                return;
            }

            if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
                RuntimeException e = new RuntimeException();
                e.fillInStackTrace();
                Log.v(TAG, "setAppVisibility(" + token + ", " + visible
                        + "): mNextAppTransition=" + mNextAppTransition
                        + " hidden=" + wtoken.hidden
                        + " hiddenRequested=" + wtoken.hiddenRequested, e);
            }
            
            // If we are preparing an app transition, then delay changing
            // the visibility of this token until we execute that transition.
            if (!mDisplayFrozen && mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
                // Already in requested state, don't do anything more.
                if (wtoken.hiddenRequested != visible) {
                    return;
                }
                wtoken.hiddenRequested = !visible;
                
                if (DEBUG_APP_TRANSITIONS) Log.v(
                        TAG, "Setting dummy animation on: " + wtoken);
                wtoken.setDummyAnimation();
                mOpeningApps.remove(wtoken);
                mClosingApps.remove(wtoken);
                wtoken.inPendingTransaction = true;
                if (visible) {
                    mOpeningApps.add(wtoken);
                    wtoken.allDrawn = false;
                    wtoken.startingDisplayed = false;
                    wtoken.startingMoved = false;
                    
                    if (wtoken.clientHidden) {
                        // In the case where we are making an app visible
                        // but holding off for a transition, we still need
                        // to tell the client to make its windows visible so
                        // they get drawn.  Otherwise, we will wait on
                        // performing the transition until all windows have
                        // been drawn, they never will be, and we are sad.
                        wtoken.clientHidden = false;
                        wtoken.sendAppVisibilityToClients();
                    }
                } else {
                    mClosingApps.add(wtoken);
                }
                return;
            }
            
            final long origId = Binder.clearCallingIdentity();
            setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_NONE, true);
            wtoken.updateReportedVisibilityLocked();
            Binder.restoreCallingIdentity(origId);
        }
    
public voidsetAppWillBeHidden(android.os.IBinder token)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setAppWillBeHidden()")) {
            return;
        }

        AppWindowToken wtoken;

        synchronized(mWindowMap) {
            wtoken = findAppWindowToken(token);
            if (wtoken == null) {
                Log.w(TAG, "Attempted to set will be hidden of non-existing app token: " + token);
                return;
            }
            wtoken.willBeHidden = true;
        }
    
public voidsetEventDispatching(boolean enabled)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "resumeKeyDispatching()")) {
            return;
        }

        synchronized (mWindowMap) {
            mKeyWaiter.setEventDispatchingLocked(enabled);
        }
    
public voidsetFocusedApp(android.os.IBinder token, boolean moveFocusNow)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setFocusedApp()")) {
            return;
        }

        synchronized(mWindowMap) {
            boolean changed = false;
            if (token == null) {
                if (DEBUG_FOCUS) Log.v(TAG, "Clearing focused app, was " + mFocusedApp);
                changed = mFocusedApp != null;
                mFocusedApp = null;
                mKeyWaiter.tickle();
            } else {
                AppWindowToken newFocus = findAppWindowToken(token);
                if (newFocus == null) {
                    Log.w(TAG, "Attempted to set focus to non-existing app token: " + token);
                    return;
                }
                changed = mFocusedApp != newFocus;
                mFocusedApp = newFocus;
                if (DEBUG_FOCUS) Log.v(TAG, "Set focused app to: " + mFocusedApp);
                mKeyWaiter.tickle();
            }

            if (moveFocusNow && changed) {
                final long origId = Binder.clearCallingIdentity();
                updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
                Binder.restoreCallingIdentity(origId);
            }
        }
    
public voidsetInTouchMode(boolean mode)

        synchronized(mWindowMap) {
            mInTouchMode = mode;
        }
    
voidsetInputMethodAnimLayerAdjustment(int adj)

        if (DEBUG_LAYERS) Log.v(TAG, "Setting im layer adj to " + adj);
        mInputMethodAnimLayerAdjustment = adj;
        WindowState imw = mInputMethodWindow;
        if (imw != null) {
            imw.mAnimLayer = imw.mLayer + adj;
            if (DEBUG_LAYERS) Log.v(TAG, "IM win " + imw
                    + " anim layer: " + imw.mAnimLayer);
            int wi = imw.mChildWindows.size();
            while (wi > 0) {
                wi--;
                WindowState cw = (WindowState)imw.mChildWindows.get(wi);
                cw.mAnimLayer = cw.mLayer + adj;
                if (DEBUG_LAYERS) Log.v(TAG, "IM win " + cw
                        + " anim layer: " + cw.mAnimLayer);
            }
        }
        int di = mInputMethodDialogs.size();
        while (di > 0) {
            di --;
            imw = mInputMethodDialogs.get(di);
            imw.mAnimLayer = imw.mLayer + adj;
            if (DEBUG_LAYERS) Log.v(TAG, "IM win " + imw
                    + " anim layer: " + imw.mAnimLayer);
        }
    
voidsetInsetsWindow(com.android.server.WindowManagerService$Session session, android.view.IWindow client, int touchableInsets, android.graphics.Rect contentInsets, android.graphics.Rect visibleInsets)

        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mWindowMap) {
                WindowState w = windowForClientLocked(session, client);
                if (w != null) {
                    w.mGivenInsetsPending = false;
                    w.mGivenContentInsets.set(contentInsets);
                    w.mGivenVisibleInsets.set(visibleInsets);
                    w.mTouchableInsets = touchableInsets;
                    mLayoutNeeded = true;
                    performLayoutAndPlaceSurfacesLocked();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    
public voidsetRotation(int rotation, boolean alwaysSendConfiguration, int animFlags)

        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                "setRotation()")) {
            return;
        }

        setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
    
public voidsetRotationUnchecked(int rotation, boolean alwaysSendConfiguration, int animFlags)

        if(DEBUG_ORIENTATION) Log.v(TAG,
                "alwaysSendConfiguration set to "+alwaysSendConfiguration);
        
        long origId = Binder.clearCallingIdentity();
        boolean changed;
        synchronized(mWindowMap) {
            changed = setRotationUncheckedLocked(rotation, animFlags);
        }
        
        if (changed) {
            sendNewConfiguration();
            synchronized(mWindowMap) {
                mLayoutNeeded = true;
                performLayoutAndPlaceSurfacesLocked();
            }
        } else if (alwaysSendConfiguration) {
            //update configuration ignoring orientation change
            sendNewConfiguration();
        }
        
        Binder.restoreCallingIdentity(origId);
    
public booleansetRotationUncheckedLocked(int rotation, int animFlags)

        boolean changed;
        if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
            rotation = mRequestedRotation;
        } else {
            mRequestedRotation = rotation;
            mLastRotationFlags = animFlags;
        }
        if (DEBUG_ORIENTATION) Log.v(TAG, "Overwriting rotation value from " + rotation);
        rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
                mRotation, mDisplayEnabled);
        if (DEBUG_ORIENTATION) Log.v(TAG, "new rotation is set to " + rotation);
        changed = mDisplayEnabled && mRotation != rotation;
        
        if (changed) {
            if (DEBUG_ORIENTATION) Log.v(TAG, 
                    "Rotation changed to " + rotation
                    + " from " + mRotation
                    + " (forceApp=" + mForcedAppOrientation
                    + ", req=" + mRequestedRotation + ")");
            mRotation = rotation;
            mWindowsFreezingScreen = true;
            mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
            mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
                    2000);
            startFreezingDisplayLocked();
            Log.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
            mQueue.setOrientation(rotation);
            if (mDisplayEnabled) {
                Surface.setOrientation(0, rotation, animFlags);
            }
            for (int i=mWindows.size()-1; i>=0; i--) {
                WindowState w = (WindowState)mWindows.get(i);
                if (w.mSurface != null) {
                    w.mOrientationChanging = true;
                }
            }
            for (int i=mRotationWatchers.size()-1; i>=0; i--) {
                try {
                    mRotationWatchers.get(i).onRotationChanged(rotation);
                } catch (RemoteException e) {
                }
            }
        } //end if changed
        
        return changed;
    
booleansetTokenVisibilityLocked(com.android.server.WindowManagerService$AppWindowToken wtoken, android.view.WindowManager.LayoutParams lp, boolean visible, int transit, boolean performLayout)

        boolean delayed = false;

        if (wtoken.clientHidden == visible) {
            wtoken.clientHidden = !visible;
            wtoken.sendAppVisibilityToClients();
        }
        
        wtoken.willBeHidden = false;
        if (wtoken.hidden == visible) {
            final int N = wtoken.allAppWindows.size();
            boolean changed = false;
            if (DEBUG_APP_TRANSITIONS) Log.v(
                TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
                + " performLayout=" + performLayout);
            
            boolean runningAppAnimation = false;
            
            if (transit != WindowManagerPolicy.TRANSIT_NONE) {
                if (wtoken.animation == sDummyAnimation) {
                    wtoken.animation = null;
                }
                applyAnimationLocked(wtoken, lp, transit, visible);
                changed = true;
                if (wtoken.animation != null) {
                    delayed = runningAppAnimation = true;
                }
            }
            
            for (int i=0; i<N; i++) {
                WindowState win = wtoken.allAppWindows.get(i);
                if (win == wtoken.startingWindow) {
                    continue;
                }

                if (win.isAnimating()) {
                    delayed = true;
                }
                
                //Log.i(TAG, "Window " + win + ": vis=" + win.isVisible());
                //win.dump("  ");
                if (visible) {
                    if (!win.isVisibleNow()) {
                        if (!runningAppAnimation) {
                            applyAnimationLocked(win,
                                    WindowManagerPolicy.TRANSIT_ENTER, true);
                        }
                        changed = true;
                    }
                } else if (win.isVisibleNow()) {
                    if (!runningAppAnimation) {
                        applyAnimationLocked(win,
                                WindowManagerPolicy.TRANSIT_EXIT, false);
                    }
                    mKeyWaiter.finishedKey(win.mSession, win.mClient, true,
                            KeyWaiter.RETURN_NOTHING);
                    changed = true;
                }
            }

            wtoken.hidden = wtoken.hiddenRequested = !visible;
            if (!visible) {
                unsetAppFreezingScreenLocked(wtoken, true, true);
            } else {
                // If we are being set visible, and the starting window is
                // not yet displayed, then make sure it doesn't get displayed.
                WindowState swin = wtoken.startingWindow;
                if (swin != null && (swin.mDrawPending
                        || swin.mCommitDrawPending)) {
                    swin.mPolicyVisibility = false;
                    swin.mPolicyVisibilityAfterAnim = false;
                 }
            }
            
            if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "setTokenVisibilityLocked: " + wtoken
                      + ": hidden=" + wtoken.hidden + " hiddenRequested="
                      + wtoken.hiddenRequested);
            
            if (changed && performLayout) {
                mLayoutNeeded = true;
                updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
                performLayoutAndPlaceSurfacesLocked();
            }
        }

        if (wtoken.animation != null) {
            delayed = true;
        }
        
        return delayed;
    
private voidsetTransparentRegionWindow(com.android.server.WindowManagerService$Session session, android.view.IWindow client, android.graphics.Region region)

        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mWindowMap) {
                WindowState w = windowForClientLocked(session, client);
                if ((w != null) && (w.mSurface != null)) {
                    Surface.openTransaction();
                    try {
                        w.mSurface.setTransparentRegionHint(region);
                    } finally {
                        Surface.closeTransaction();
                    }
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    
booleanshowSurfaceRobustlyLocked(com.android.server.WindowManagerService$WindowState win)
Have the surface flinger show a surface, robustly dealing with error conditions. In particular, if there is not enough memory to show the surface, then we will try to get rid of other surfaces in order to succeed.

return
Returns true if the surface was successfully shown.

        try {
            if (win.mSurface != null) {
                win.mSurface.show();
            }
            return true;
        } catch (RuntimeException e) {
            Log.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
        }
        
        reclaimSomeSurfaceMemoryLocked(win, "show");
        
        return false;
    
public voidstartAppFreezingScreen(android.os.IBinder token, int configChanges)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setAppFreezingScreen()")) {
            return;
        }

        synchronized(mWindowMap) {
            if (configChanges == 0 && !mDisplayFrozen) {
                if (DEBUG_ORIENTATION) Log.v(TAG, "Skipping set freeze of " + token);
                return;
            }
            
            AppWindowToken wtoken = findAppWindowToken(token);
            if (wtoken == null || wtoken.appToken == null) {
                Log.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
                return;
            }
            final long origId = Binder.clearCallingIdentity();
            startAppFreezingScreenLocked(wtoken, configChanges);
            Binder.restoreCallingIdentity(origId);
        }
    
public voidstartAppFreezingScreenLocked(com.android.server.WindowManagerService$AppWindowToken wtoken, int configChanges)

        if (DEBUG_ORIENTATION) {
            RuntimeException e = new RuntimeException();
            e.fillInStackTrace();
            Log.i(TAG, "Set freezing of " + wtoken.appToken
                    + ": hidden=" + wtoken.hidden + " freezing="
                    + wtoken.freezingScreen, e);
        }
        if (!wtoken.hiddenRequested) {
            if (!wtoken.freezingScreen) {
                wtoken.freezingScreen = true;
                mAppsFreezingScreen++;
                if (mAppsFreezingScreen == 1) {
                    startFreezingDisplayLocked();
                    mH.removeMessages(H.APP_FREEZE_TIMEOUT);
                    mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
                            5000);
                }
            }
            final int N = wtoken.allAppWindows.size();
            for (int i=0; i<N; i++) {
                WindowState w = wtoken.allAppWindows.get(i);
                w.mAppFreezing = true;
            }
        }
    
private voidstartFreezingDisplayLocked()

        if (mDisplayFrozen) {
            // Freezing the display also suspends key event delivery, to
            // keep events from going astray while the display is reconfigured.
            // If someone has changed orientation again while the screen is
            // still frozen, the events will continue to be blocked while the
            // successive orientation change is processed.  To prevent spurious
            // ANRs, we reset the event dispatch timeout in this case.
            synchronized (mKeyWaiter) {
                mKeyWaiter.mWasFrozen = true;
            }
            return;
        }
        
        mScreenFrozenLock.acquire();
        
        long now = SystemClock.uptimeMillis();
        //Log.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
        if (mFreezeGcPending != 0) {
            if (now > (mFreezeGcPending+1000)) {
                //Log.i(TAG, "Gc!  " + now + " > " + (mFreezeGcPending+1000));
                mH.removeMessages(H.FORCE_GC);
                Runtime.getRuntime().gc();
                mFreezeGcPending = now;
            }
        } else {
            mFreezeGcPending = now;
        }
        
        mDisplayFrozen = true;
        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
            mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
            mAppTransitionReady = true;
        }
        
        if (PROFILE_ORIENTATION) {
            File file = new File("/data/system/frozen");
            Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
        }
        Surface.freezeDisplay(0);
    
public booleanstartViewServer(int port)
Starts the view server on the specified port.

param
port The port to listener to.
return
True if the server was successfully started, false otherwise.
see
com.android.server.ViewServer
see
com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT

        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
            return false;
        }

        if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
            return false;
        }

        if (port < 1024) {
            return false;
        }

        if (mViewServer != null) {
            if (!mViewServer.isRunning()) {
                try {
                    return mViewServer.start();
                } catch (IOException e) {
                    Log.w(TAG, "View server did not start");                    
                }
            }
            return false;
        }

        try {
            mViewServer = new ViewServer(this, port);
            return mViewServer.start();
        } catch (IOException e) {
            Log.w(TAG, "View server did not start");
        }
        return false;
    
public voidstopAppFreezingScreen(android.os.IBinder token, boolean force)

        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setAppFreezingScreen()")) {
            return;
        }

        synchronized(mWindowMap) {
            AppWindowToken wtoken = findAppWindowToken(token);
            if (wtoken == null || wtoken.appToken == null) {
                return;
            }
            final long origId = Binder.clearCallingIdentity();
            if (DEBUG_ORIENTATION) Log.v(TAG, "Clear freezing of " + token
                    + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen);
            unsetAppFreezingScreenLocked(wtoken, true, force);
            Binder.restoreCallingIdentity(origId);
        }
    
private voidstopFreezingDisplayLocked()

        if (!mDisplayFrozen) {
            return;
        }
        
        mDisplayFrozen = false;
        mH.removeMessages(H.APP_FREEZE_TIMEOUT);
        if (PROFILE_ORIENTATION) {
            Debug.stopMethodTracing();
        }
        Surface.unfreezeDisplay(0);
        
        // Reset the key delivery timeout on unfreeze, too.  We force a wakeup here
        // too because regular key delivery processing should resume immediately.
        synchronized (mKeyWaiter) {
            mKeyWaiter.mWasFrozen = true;
            mKeyWaiter.notifyAll();
        }

        // A little kludge: a lot could have happened while the
        // display was frozen, so now that we are coming back we
        // do a gc so that any remote references the system
        // processes holds on others can be released if they are
        // no longer needed.
        mH.removeMessages(H.FORCE_GC);
        mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
                2000);
        
        mScreenFrozenLock.release();
    
public booleanstopViewServer()
Stops the view server if it exists.

return
True if the server stopped, false if it wasn't started or couldn't be stopped.
see
com.android.server.ViewServer

        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
            return false;
        }

        if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
            return false;
        }

        if (mViewServer != null) {
            return mViewServer.stop();
        }
        return false;
    
public voidsystemReady()

        mPolicy.systemReady();
    
private booleantmpRemoveAppWindowsLocked(com.android.server.WindowManagerService$WindowToken token)

        final int NW = token.windows.size();
        for (int i=0; i<NW; i++) {
            WindowState win = token.windows.get(i);
            mWindows.remove(win);
            int j = win.mChildWindows.size();
            while (j > 0) {
                j--;
                mWindows.remove(win.mChildWindows.get(j));
            }
        }
        return NW > 0;
    
private inttmpRemoveWindowLocked(int interestingPos, com.android.server.WindowManagerService$WindowState win)

        int wpos = mWindows.indexOf(win);
        if (wpos >= 0) {
            if (wpos < interestingPos) interestingPos--;
            mWindows.remove(wpos);
            int NC = win.mChildWindows.size();
            while (NC > 0) {
                NC--;
                WindowState cw = (WindowState)win.mChildWindows.get(NC);
                int cpos = mWindows.indexOf(cw);
                if (cpos >= 0) {
                    if (cpos < interestingPos) interestingPos--;
                    mWindows.remove(cpos);
                }
            }
        }
        return interestingPos;
    
voidunsetAppFreezingScreenLocked(com.android.server.WindowManagerService$AppWindowToken wtoken, boolean unfreezeSurfaceNow, boolean force)

        if (wtoken.freezingScreen) {
            if (DEBUG_ORIENTATION) Log.v(TAG, "Clear freezing of " + wtoken
                    + " force=" + force);
            final int N = wtoken.allAppWindows.size();
            boolean unfrozeWindows = false;
            for (int i=0; i<N; i++) {
                WindowState w = wtoken.allAppWindows.get(i);
                if (w.mAppFreezing) {
                    w.mAppFreezing = false;
                    if (w.mSurface != null && !w.mOrientationChanging) {
                        w.mOrientationChanging = true;
                    }
                    unfrozeWindows = true;
                }
            }
            if (force || unfrozeWindows) {
                if (DEBUG_ORIENTATION) Log.v(TAG, "No longer freezing: " + wtoken);
                wtoken.freezingScreen = false;
                mAppsFreezingScreen--;
            }
            if (unfreezeSurfaceNow) {
                if (unfrozeWindows) {
                    mLayoutNeeded = true;
                    performLayoutAndPlaceSurfacesLocked();
                }
                if (mAppsFreezingScreen == 0 && !mWindowsFreezingScreen) {
                    stopFreezingDisplayLocked();
                }
            }
        }
    
private booleanupdateFocusedWindowLocked(int mode)

        WindowState newFocus = computeFocusedWindowLocked();
        if (mCurrentFocus != newFocus) {
            // This check makes sure that we don't already have the focus
            // change message pending.
            mH.removeMessages(H.REPORT_FOCUS_CHANGE);
            mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
            if (localLOGV) Log.v(
                TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
            final WindowState oldFocus = mCurrentFocus;
            mCurrentFocus = newFocus;
            mLosingFocus.remove(newFocus);
            
            final WindowState imWindow = mInputMethodWindow;
            if (newFocus != imWindow && oldFocus != imWindow) {
                if (moveInputMethodWindowsIfNeededLocked(
                        mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
                        mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
                    mLayoutNeeded = true;
                }
                if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
                    performLayoutLockedInner();
                } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
                    // Client will do the layout, but we need to assign layers
                    // for handleNewWindowLocked() below.
                    assignLayersLocked();
                }
            }
            
            if (newFocus != null && mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
                mKeyWaiter.handleNewWindowLocked(newFocus);
            }
            return true;
        }
        return false;
    
public android.content.res.ConfigurationupdateOrientationFromAppTokens(android.content.res.Configuration currentConfig, android.os.IBinder freezeThisOneIfNeeded)

        Configuration config;
        long ident = Binder.clearCallingIdentity();
        synchronized(mWindowMap) {
            config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded);
        }
        if (config != null) {
            mLayoutNeeded = true;
            performLayoutAndPlaceSurfacesLocked();
        }
        Binder.restoreCallingIdentity(ident);
        return config;
    
android.content.res.ConfigurationupdateOrientationFromAppTokensLocked(android.content.res.Configuration appConfig, android.os.IBinder freezeThisOneIfNeeded)

        boolean changed = false;
        long ident = Binder.clearCallingIdentity();
        try {
            int req = computeForcedAppOrientationLocked();
            
            if (req != mForcedAppOrientation) {
                changed = true;
                mForcedAppOrientation = req;
                //send a message to Policy indicating orientation change to take
                //action like disabling/enabling sensors etc.,
                mPolicy.setCurrentOrientationLw(req);
            }
            
            if (changed) {
                changed = setRotationUncheckedLocked(
                        WindowManagerPolicy.USE_LAST_ROTATION,
                        mLastRotationFlags & (~Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE));
                if (changed) {
                    if (freezeThisOneIfNeeded != null) {
                        AppWindowToken wtoken = findAppWindowToken(
                                freezeThisOneIfNeeded);
                        if (wtoken != null) {
                            startAppFreezingScreenLocked(wtoken,
                                    ActivityInfo.CONFIG_ORIENTATION);
                        }
                    }
                    return computeNewConfigurationLocked();
                }
            }

            // No obvious action we need to take, but if our current
            // state mismatches the activity maanager's, update it
            if (appConfig != null) {
                mTempConfiguration.setToDefaults();
                if (computeNewConfigurationLocked(mTempConfiguration)) {
                    if (appConfig.diff(mTempConfiguration) != 0) {
                        Log.i(TAG, "Config changed: " + mTempConfiguration);
                        return new Configuration(mTempConfiguration);
                    }
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        
        return null;
    
public voidvalidateAppTokens(java.util.List tokens)

        int v = tokens.size()-1;
        int m = mAppTokens.size()-1;
        while (v >= 0 && m >= 0) {
            AppWindowToken wtoken = mAppTokens.get(m);
            if (wtoken.removed) {
                m--;
                continue;
            }
            if (tokens.get(v) != wtoken.token) {
                Log.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
                      + " @ " + v + ", internal is " + wtoken.token + " @ " + m);
            }
            v--;
            m--;
        }
        while (v >= 0) {
            Log.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
            v--;
        }
        while (m >= 0) {
            AppWindowToken wtoken = mAppTokens.get(m);
            if (!wtoken.removed) {
                Log.w(TAG, "Invalid internal token: " + wtoken.token + " @ " + m);
            }
            m--;
        }
    
booleanviewServerListWindows(java.net.Socket client)
Lists all availble windows in the system. The listing is written in the specified Socket's output stream with the following syntax: windowHashCodeInHexadecimal windowName Each line of the ouput represents a different window.

param
client The remote client to send the listing to.
return
False if an error occured, true otherwise.

        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
            return false;
        }

        boolean result = true;

        Object[] windows;
        synchronized (mWindowMap) {
            windows = new Object[mWindows.size()];
            //noinspection unchecked
            windows = mWindows.toArray(windows);
        }

        BufferedWriter out = null;

        // Any uncaught exception will crash the system process
        try {
            OutputStream clientStream = client.getOutputStream();
            out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);

            final int count = windows.length;
            for (int i = 0; i < count; i++) {
                final WindowState w = (WindowState) windows[i];
                out.write(Integer.toHexString(System.identityHashCode(w)));
                out.write(' ");
                out.append(w.mAttrs.getTitle());
                out.write('\n");
            }

            out.write("DONE.\n");
            out.flush();
        } catch (Exception e) {
            result = false;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    result = false;
                }
            }
        }

        return result;
    
booleanviewServerWindowCommand(java.net.Socket client, java.lang.String command, java.lang.String parameters)
Sends a command to a target window. The result of the command, if any, will be written in the output stream of the specified socket. The parameters must follow this syntax: windowHashcode extra Where XX is the length in characeters of the windowTitle. The first parameter is the target window. The window with the specified hashcode will be the target. If no target can be found, nothing happens. The extra parameters will be delivered to the target window and as parameters to the command itself.

param
client The remote client to sent the result, if any, to.
param
command The command to execute.
param
parameters The command parameters.
return
True if the command was successfully delivered, false otherwise. This does not indicate whether the command itself was successful.

        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
            return false;
        }

        boolean success = true;
        Parcel data = null;
        Parcel reply = null;

        // Any uncaught exception will crash the system process
        try {
            // Find the hashcode of the window
            int index = parameters.indexOf(' ");
            if (index == -1) {
                index = parameters.length();
            }
            final String code = parameters.substring(0, index);
            int hashCode = "ffffffff".equals(code) ? -1 : Integer.parseInt(code, 16);

            // Extract the command's parameter after the window description
            if (index < parameters.length()) {
                parameters = parameters.substring(index + 1);
            } else {
                parameters = "";
            }

            final WindowManagerService.WindowState window = findWindow(hashCode);
            if (window == null) {
                return false;
            }

            data = Parcel.obtain();
            data.writeInterfaceToken("android.view.IWindow");
            data.writeString(command);
            data.writeString(parameters);
            data.writeInt(1);
            ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);

            reply = Parcel.obtain();

            final IBinder binder = window.mClient.asBinder();
            // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
            binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);

            reply.readException();

        } catch (Exception e) {
            Log.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
            success = false;
        } finally {
            if (data != null) {
                data.recycle();
            }
            if (reply != null) {
                reply.recycle();
            }
        }

        return success;
    
private final voidwakeupIfNeeded(com.android.server.WindowManagerService$WindowState targetWin, int eventType)

        if (targetWin == null ||
                targetWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
            mPowerManager.userActivity(SystemClock.uptimeMillis(), false, eventType);
        }
    
public intwatchRotation(android.view.IRotationWatcher watcher)

        final IBinder watcherBinder = watcher.asBinder();
        IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
            public void binderDied() {
                synchronized (mWindowMap) {
                    for (int i=0; i<mRotationWatchers.size(); i++) {
                        if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
                            mRotationWatchers.remove(i);
                            i--;
                        }
                    }
                }
            }
        };
        
        synchronized (mWindowMap) {
            try {
                watcher.asBinder().linkToDeath(dr, 0);
                mRotationWatchers.add(watcher);
            } catch (RemoteException e) {
                // Client died, no cleanup needed.
            }
            
            return mRotation;
        }
    
final com.android.server.WindowManagerService$WindowStatewindowForClientLocked(com.android.server.WindowManagerService$Session session, android.view.IWindow client)

        return windowForClientLocked(session, client.asBinder());
    
final com.android.server.WindowManagerService$WindowStatewindowForClientLocked(com.android.server.WindowManagerService$Session session, android.os.IBinder client)

        WindowState win = mWindowMap.get(client);
        if (localLOGV) Log.v(
            TAG, "Looking up client " + client + ": " + win);
        if (win == null) {
            RuntimeException ex = new RuntimeException();
            Log.w(TAG, "Requested window " + client + " does not exist", ex);
            return null;
        }
        if (session != null && win.mSession != session) {
            RuntimeException ex = new RuntimeException();
            Log.w(TAG, "Requested window " + client + " is in session " +
                  win.mSession + ", not " + session, ex);
            return null;
        }

        return win;