donut snapshot
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3fa5baf..2dd70ef 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -77,6 +77,7 @@
 import android.os.SystemProperties;
 import android.os.TokenWatcher;
 import android.provider.Settings;
+import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.SparseIntArray;
@@ -133,16 +134,16 @@
     static final boolean DEBUG_STARTING_WINDOW = false;
     static final boolean DEBUG_REORDER = false;
     static final boolean SHOW_TRANSACTIONS = false;
-    
+
     static final boolean PROFILE_ORIENTATION = false;
     static final boolean BLUR = true;
     static final boolean localLOGV = DEBUG;
-    
+
     static final int LOG_WM_NO_SURFACE_MEMORY = 31000;
-    
+
     /** How long to wait for first key repeat, in milliseconds */
     static final int KEY_REPEAT_FIRST_DELAY = 750;
-    
+
     /** How long to wait for subsequent key repeats, in milliseconds */
     static final int KEY_REPEAT_DELAY = 50;
 
@@ -150,16 +151,16 @@
      * for multiple windows of the same type and Z-ordering adjustment
      * with TYPE_LAYER_OFFSET. */
     static final int TYPE_LAYER_MULTIPLIER = 10000;
-    
+
     /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
      * or below others in the same layer. */
     static final int TYPE_LAYER_OFFSET = 1000;
-    
+
     /** How much to increment the layer for each window, to reserve room
      * for effect surfaces between them.
      */
     static final int WINDOW_LAYER_MULTIPLIER = 5;
-    
+
     /** The maximum length we will accept for a loaded animation duration:
      * this is 10 seconds.
      */
@@ -173,21 +174,25 @@
     /** Adjustment to time to perform a dim, to make it more dramatic.
      */
     static final int DIM_DURATION_MULTIPLIER = 6;
+
+    static final int INJECT_FAILED = 0;
+    static final int INJECT_SUCCEEDED = 1;
+    static final int INJECT_NO_PERMISSION = -1;
     
     static final int UPDATE_FOCUS_NORMAL = 0;
     static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
     static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
     static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
-    
+
     /** The minimum time between dispatching touch events. */
     int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
 
     // Last touch event time
     long mLastTouchEventTime = 0;
-    
+
     // Last touch event type
     int mLastTouchEventType = OTHER_EVENT;
-    
+
     // Time to wait before calling useractivity again. This saves CPU usage
     // when we get a flood of touch events.
     static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
@@ -195,10 +200,11 @@
     // Last time we call user activity
     long mLastUserActivityCallTime = 0;
 
-    // Last time we updated battery stats 
+    // Last time we updated battery stats
     long mLastBatteryStatsCallTime = 0;
-    
+
     private static final String SYSTEM_SECURE = "ro.secure";
+    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
     /**
      * Condition waited on by {@link #reenableKeyguard} to know the call to
@@ -224,20 +230,20 @@
     final Context mContext;
 
     final boolean mHaveInputMethods;
-    
+
     final boolean mLimitedAlphaCompositing;
-    
+
     final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
 
     final IActivityManager mActivityManager;
-    
+
     final IBatteryStats mBatteryStats;
-    
+
     /**
      * All currently active sessions with clients.
      */
     final HashSet<Session> mSessions = new HashSet<Session>();
-    
+
     /**
      * Mapping from an IWindow IBinder to the server's Window object.
      * This is also used as the lock for all of our state.
@@ -255,7 +261,7 @@
      * over them.
      */
     final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
-    
+
     /**
      * Window tokens that are in the process of exiting, but still
      * on screen for animations.
@@ -314,9 +320,9 @@
      * list or contain windows that need to be force removed.
      */
     ArrayList<WindowState> mForceRemoves;
-    
+
     IInputMethodManager mInputMethodManager;
-    
+
     SurfaceSession mFxSession;
     Surface mDimSurface;
     boolean mDimShown;
@@ -326,9 +332,9 @@
     long mLastDimAnimTime;
     Surface mBlurSurface;
     boolean mBlurShown;
-    
+
     int mTransactionSequence = 0;
-    
+
     final float[] mTmpFloats = new float[9];
 
     boolean mSafeMode;
@@ -340,7 +346,7 @@
     int mLastRotationFlags;
     ArrayList<IRotationWatcher> mRotationWatchers
             = new ArrayList<IRotationWatcher>();
-    
+
     boolean mLayoutNeeded = true;
     boolean mAnimationPending = false;
     boolean mDisplayFrozen = false;
@@ -352,7 +358,7 @@
     // perform a rotation animation when turning off shows the lock screen which
     // changes the orientation.
     PowerManager.WakeLock mScreenFrozenLock;
-    
+
     // State management of app transitions.  When we are preparing for a
     // transition, mNextAppTransition will be the kind of transition to
     // perform or TRANSIT_NONE if we are not waiting.  If we are waiting,
@@ -365,40 +371,40 @@
     boolean mSkipAppTransitionAnimation = false;
     final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
     final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
-    
+
     //flag to detect fat touch events
     boolean mFatTouch = false;
     Display mDisplay;
-    
+
     H mH = new H();
 
     WindowState mCurrentFocus = null;
     WindowState mLastFocus = null;
-    
+
     // This just indicates the window the input method is on top of, not
     // necessarily the window its input is going to.
     WindowState mInputMethodTarget = null;
     WindowState mUpcomingInputMethodTarget = null;
     boolean mInputMethodTargetWaitingAnim;
     int mInputMethodAnimLayerAdjustment;
-    
+
     WindowState mInputMethodWindow = null;
     final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
 
     AppWindowToken mFocusedApp = null;
 
     PowerManagerService mPowerManager;
-    
+
     float mWindowAnimationScale = 1.0f;
     float mTransitionAnimationScale = 1.0f;
-    
+
     final KeyWaiter mKeyWaiter = new KeyWaiter();
     final KeyQ mQueue;
     final InputDispatcherThread mInputThread;
 
     // Who is holding the screen on.
     Session mHoldingScreenOn;
-    
+
     /**
      * Whether the UI is currently running in touch mode (not showing
      * navigational focus because the user is directly pressing the screen).
@@ -408,14 +414,15 @@
     private ViewServer mViewServer;
 
     final Rect mTempRect = new Rect();
-    
+
     final Configuration mTempConfiguration = new Configuration();
+    int screenLayout = Configuration.SCREENLAYOUT_UNDEFINED;
     
     public static WindowManagerService main(Context context,
             PowerManagerService pm, boolean haveInputMethods) {
         WMThread thr = new WMThread(context, pm, haveInputMethods);
         thr.start();
-        
+
         synchronized (thr) {
             while (thr.mService == null) {
                 try {
@@ -424,17 +431,17 @@
                 }
             }
         }
-        
+
         return thr.mService;
     }
-    
+
     static class WMThread extends Thread {
         WindowManagerService mService;
-        
+
         private final Context mContext;
         private final PowerManagerService mPM;
         private final boolean mHaveInputMethods;
-        
+
         public WMThread(Context context, PowerManagerService pm,
                 boolean haveInputMethods) {
             super("WindowManager");
@@ -442,19 +449,19 @@
             mPM = pm;
             mHaveInputMethods = haveInputMethods;
         }
-        
+
         public void run() {
             Looper.prepare();
             WindowManagerService s = new WindowManagerService(mContext, mPM,
                     mHaveInputMethods);
             android.os.Process.setThreadPriority(
                     android.os.Process.THREAD_PRIORITY_DISPLAY);
-            
+
             synchronized (this) {
                 mService = s;
                 notifyAll();
             }
-            
+
             Looper.loop();
         }
     }
@@ -465,7 +472,7 @@
         private final Context mContext;
         private final PowerManagerService mPM;
         boolean mRunning = false;
-        
+
         public PolicyThread(WindowManagerPolicy policy,
                 WindowManagerService service, Context context,
                 PowerManagerService pm) {
@@ -475,7 +482,7 @@
             mContext = context;
             mPM = pm;
         }
-        
+
         public void run() {
             Looper.prepare();
             //Looper.myLooper().setMessageLogging(new LogPrinter(
@@ -483,12 +490,12 @@
             android.os.Process.setThreadPriority(
                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
             mPolicy.init(mContext, mService, mPM);
-            
+
             synchronized (this) {
                 mRunning = true;
                 notifyAll();
             }
-            
+
             Looper.loop();
         }
     }
@@ -499,7 +506,7 @@
         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);
@@ -515,14 +522,14 @@
                 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 {
@@ -531,9 +538,9 @@
                 }
             }
         }
-        
+
         mInputThread.start();
-        
+
         // Add ourself to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
     }
@@ -586,12 +593,12 @@
         }
         return -1;
     }
-    
+
     private void addWindowToListInOrderLocked(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;
@@ -616,12 +623,12 @@
                         } 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 
+                                //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 {
@@ -647,7 +654,7 @@
                     // we need to look some more.
                     if (pos != null) {
                         // Move behind any windows attached to this one.
-                        WindowToken atoken = 
+                        WindowToken atoken =
                             mTokenMap.get(((WindowState)pos).mClient.asBinder());
                         if (atoken != null) {
                             final int NC = atoken.windows.size();
@@ -770,12 +777,12 @@
                 }
             }
         }
-        
+
         if (win.mAppToken != null && addToToken) {
             win.mAppToken.allAppWindows.add(win);
         }
     }
-    
+
     static boolean canBeImeTarget(WindowState w) {
         final int fl = w.mAttrs.flags
                 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
@@ -784,7 +791,7 @@
         }
         return false;
     }
-    
+
     int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
         final ArrayList localmWindows = mWindows;
         final int N = localmWindows.size();
@@ -793,12 +800,12 @@
         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
@@ -816,16 +823,16 @@
                 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
@@ -851,14 +858,14 @@
                         pos--;
                     }
                 }
-                
+
                 if (highestTarget != null) {
-                    if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition=" 
+                    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.
@@ -877,7 +884,7 @@
                 }
             }
         }
-        
+
         //Log.i(TAG, "Placing input method @" + (i+1));
         if (w != null) {
             if (willMove) {
@@ -904,7 +911,7 @@
         }
         return -1;
     }
-    
+
     void addInputMethodWindowToListLocked(WindowState win) {
         int pos = findDesiredInputMethodWindowIndexLocked(true);
         if (pos >= 0) {
@@ -917,7 +924,7 @@
         addWindowToListInOrderLocked(win, true);
         moveInputMethodDialogsLocked(pos);
     }
-    
+
     void setInputMethodAnimLayerAdjustment(int adj) {
         if (DEBUG_LAYERS) Log.v(TAG, "Setting im layer adj to " + adj);
         mInputMethodAnimLayerAdjustment = adj;
@@ -944,7 +951,7 @@
                     + " anim layer: " + imw.mAnimLayer);
         }
     }
-    
+
     private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
         int wpos = mWindows.indexOf(win);
         if (wpos >= 0) {
@@ -963,7 +970,7 @@
         }
         return interestingPos;
     }
-    
+
     private void reAddWindowToListInOrderLocked(WindowState win) {
         addWindowToListInOrderLocked(win, false);
         // This is a hack to get all of the child windows added as well
@@ -975,7 +982,7 @@
             reAddWindowLocked(wpos, win);
         }
     }
-    
+
     void logWindowList(String prefix) {
         int N = mWindows.size();
         while (N > 0) {
@@ -983,10 +990,10 @@
             Log.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
         }
     }
-    
+
     void moveInputMethodDialogsLocked(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++) {
@@ -996,7 +1003,7 @@
             Log.v(TAG, "Window list w/pos=" + pos);
             logWindowList("  ");
         }
-        
+
         if (pos >= 0) {
             final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
             if (pos < mWindows.size()) {
@@ -1027,25 +1034,25 @@
             }
         }
     }
-    
+
     boolean moveInputMethodWindowsIfNeededLocked(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
@@ -1054,7 +1061,7 @@
                 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.
@@ -1078,7 +1085,7 @@
                     return false;
                 }
             }
-            
+
             if (imWin != null) {
                 if (DEBUG_INPUT_METHOD) {
                     Log.v(TAG, "Moving IM from " + imPos);
@@ -1099,11 +1106,11 @@
             } 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);
@@ -1117,20 +1124,20 @@
             } else {
                 moveInputMethodDialogsLocked(-1);;
             }
-            
+
         }
-        
+
         if (needAssignLayers) {
             assignLayersLocked();
         }
-        
+
         return true;
     }
-    
+
     void adjustInputMethodDialogsLocked() {
         moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
     }
-    
+
     public int addWindow(Session session, IWindow client,
             WindowManager.LayoutParams attrs, int viewVisibility,
             Rect outContentInsets) {
@@ -1138,11 +1145,11 @@
         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
@@ -1153,14 +1160,14 @@
                 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); 
+                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.");
@@ -1227,7 +1234,7 @@
             }
 
             mPolicy.adjustWindowParamsLw(win.mAttrs);
-            
+
             res = mPolicy.prepareAddWindowLw(win, attrs);
             if (res != WindowManagerImpl.ADD_OKAY) {
                 return res;
@@ -1236,9 +1243,9 @@
             // 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);
@@ -1252,7 +1259,7 @@
             }
 
             boolean imMayMove = true;
-            
+
             if (attrs.type == TYPE_INPUT_METHOD) {
                 mInputMethodWindow = win;
                 addInputMethodWindowToListLocked(win);
@@ -1265,18 +1272,18 @@
             } 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))
@@ -1284,15 +1291,15 @@
                     imMayMove = false;
                 }
             }
-            
+
             if (imMayMove) {
-                moveInputMethodWindowsIfNeededLocked(false);                
+                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) {
@@ -1300,7 +1307,6 @@
                     mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
                 }
             }
-            
             if (localLOGV) Log.v(
                 TAG, "New client " + client.asBinder()
                 + ": window=" + win);
@@ -1317,16 +1323,16 @@
             // Update Orientation after adding a window, only if the window needs to be
             // displayed right away
             if (win.isVisibleOrAdding()) {
-                if (updateOrientationFromAppTokens(null, null) != null) {
+                if (updateOrientationFromAppTokensUnchecked(null, null) != null) {
                     sendNewConfiguration();
                 }
             }
         }
         Binder.restoreCallingIdentity(origId);
-        
+
         return res;
     }
-    
+
     public void removeWindow(Session session, IWindow client) {
         synchronized(mWindowMap) {
             WindowState win = windowForClientLocked(session, client);
@@ -1336,7 +1342,7 @@
             removeWindowLocked(session, win);
         }
     }
-    
+
     public void removeWindowLocked(Session session, WindowState win) {
 
         if (localLOGV || DEBUG_FOCUS) Log.v(
@@ -1346,7 +1352,7 @@
             + ", surface=" + win.mSurface);
 
         final long origId = Binder.clearCallingIdentity();
-        
+
         if (DEBUG_APP_TRANSITIONS) Log.v(
                 TAG, "Remove " + win + ": mSurface=" + win.mSurface
                 + " mExiting=" + win.mExiting
@@ -1366,7 +1372,7 @@
             // 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;
@@ -1403,17 +1409,17 @@
         updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
         Binder.restoreCallingIdentity(origId);
     }
-    
+
     private void removeWindowInnerLocked(Session session, WindowState win) {
         mKeyWaiter.releasePendingPointerLocked(win.mSession);
         mKeyWaiter.releasePendingTrackballLocked(win.mSession);
-        
+
         win.mRemoved = true;
-        
+
         if (mInputMethodTarget == win) {
             moveInputMethodWindowsIfNeededLocked(false);
         }
-        
+
         mPolicy.removeWindowLw(win);
         win.removeLocked();
 
@@ -1425,7 +1431,7 @@
         } 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);
@@ -1462,7 +1468,7 @@
                 mH.sendMessage(m);
             }
         }
-        
+
         if (!mInLayout) {
             assignLayersLocked();
             mLayoutNeeded = true;
@@ -1493,7 +1499,7 @@
     }
 
     void setInsetsWindow(Session session, IWindow client,
-            int touchableInsets, Rect contentInsets, 
+            int touchableInsets, Rect contentInsets,
             Rect visibleInsets) {
         long origId = Binder.clearCallingIdentity();
         try {
@@ -1512,7 +1518,7 @@
             Binder.restoreCallingIdentity(origId);
         }
     }
-    
+
     public void getWindowDisplayFrame(Session session, IWindow client,
             Rect outDisplayFrame) {
         synchronized(mWindowMap) {
@@ -1534,7 +1540,7 @@
         boolean inTouchMode;
         Configuration newConfig = null;
         long origId = Binder.clearCallingIdentity();
-        
+
         synchronized(mWindowMap) {
             WindowState win = windowForClientLocked(session, client);
             if (win == null) {
@@ -1546,7 +1552,7 @@
             if (attrs != null) {
                 mPolicy.adjustWindowParamsLw(attrs);
             }
-            
+
             int attrChanges = 0;
             int flagChanges = 0;
             if (attrs != null) {
@@ -1578,11 +1584,11 @@
             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;
@@ -1670,17 +1676,17 @@
                 }
                 //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) {
@@ -1696,7 +1702,7 @@
             outVisibleInsets.set(win.mVisibleInsets);
             if (localLOGV) Log.v(
                 TAG, "Relayout given client " + client.asBinder()
-                + ", requestedWidth=" + requestedWidth 
+                + ", requestedWidth=" + requestedWidth
                 + ", requestedHeight=" + requestedHeight
                 + ", viewVisibility=" + viewVisibility
                 + "\nRelayout returning frame=" + outFrame
@@ -1711,9 +1717,9 @@
         if (newConfig != null) {
             sendNewConfiguration();
         }
-        
+
         Binder.restoreCallingIdentity(origId);
-        
+
         return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
                 | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
     }
@@ -1750,7 +1756,7 @@
         }
         return null;
     }
-    
+
     private void applyEnterAnimationLocked(WindowState win) {
         int transit = WindowManagerPolicy.TRANSIT_SHOW;
         if (win.mEnterAnimationPending) {
@@ -1768,7 +1774,7 @@
             // 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
@@ -1833,7 +1839,7 @@
         }
         return null;
     }
-    
+
     private boolean applyAnimationLocked(AppWindowToken wtoken,
             WindowManager.LayoutParams lp, int transit, boolean enter) {
         // Only apply an animation if the display isn't frozen.  If it is
@@ -1932,7 +1938,7 @@
         if (Binder.getCallingPid() == Process.myPid()) {
             return true;
         }
-        
+
         if (mContext.checkCallingPermission(permission)
                 == PackageManager.PERMISSION_GRANTED) {
             return true;
@@ -1944,7 +1950,7 @@
         Log.w(TAG, msg);
         return false;
     }
-    
+
     AppWindowToken findAppWindowToken(IBinder token) {
         WindowToken wtoken = mTokenMap.get(token);
         if (wtoken == null) {
@@ -1952,13 +1958,13 @@
         }
         return wtoken.appWindowToken;
     }
-    
+
     public void addWindowToken(IBinder token, int type) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "addWindowToken()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
-        
+
         synchronized(mWindowMap) {
             WindowToken wtoken = mTokenMap.get(token);
             if (wtoken != null) {
@@ -1970,11 +1976,11 @@
             mTokenList.add(wtoken);
         }
     }
-    
+
     public void removeWindowToken(IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "removeWindowToken()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         final long origId = Binder.clearCallingIdentity();
@@ -1985,17 +1991,17 @@
                 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);
@@ -2010,12 +2016,12 @@
                         performLayoutAndPlaceSurfacesLocked();
                         updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
                     }
-                    
+
                     if (delayed) {
                         mExitingTokens.add(wtoken);
                     }
                 }
-                
+
             } else {
                 Log.w(TAG, "Attempted to remove non-existing token: " + token);
             }
@@ -2027,9 +2033,9 @@
             int groupId, int requestedOrientation, boolean fullscreen) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "addAppToken()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
-        
+
         synchronized(mWindowMap) {
             AppWindowToken wtoken = findAppWindowToken(token.asBinder());
             if (wtoken != null) {
@@ -2044,19 +2050,19 @@
             if (localLOGV) 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();
         }
     }
-   
+
     public void setAppGroupId(IBinder token, int groupId) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppStartingIcon()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized(mWindowMap) {
@@ -2068,7 +2074,7 @@
             wtoken.groupId = groupId;
         }
     }
-    
+
     public int getOrientationFromWindowsLocked() {
         int pos = mWindows.size() - 1;
         while (pos >= 0) {
@@ -2092,7 +2098,7 @@
         }
         return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     }
-    
+
     public int getOrientationFromAppTokensLocked() {
             int pos = mAppTokens.size() - 1;
             int curGroup = 0;
@@ -2134,7 +2140,7 @@
                 // to use the orientation behind it, then just take whatever
                 // orientation it has and ignores whatever is under it.
                 lastFullscreen = wtoken.appFullscreen;
-                if (lastFullscreen 
+                if (lastFullscreen
                         && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
                     return or;
                 }
@@ -2151,11 +2157,25 @@
             }
             return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     }
-    
+
     public Configuration updateOrientationFromAppTokens(
             Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
+        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
+                "updateOrientationFromAppTokens()")) {
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
+        }
+        
         Configuration config;
         long ident = Binder.clearCallingIdentity();
+        config = updateOrientationFromAppTokensUnchecked(currentConfig,
+                freezeThisOneIfNeeded);
+        Binder.restoreCallingIdentity(ident);
+        return config;
+    }
+
+    Configuration updateOrientationFromAppTokensUnchecked(
+            Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
+        Configuration config;
         synchronized(mWindowMap) {
             config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded);
         }
@@ -2163,14 +2183,13 @@
             mLayoutNeeded = true;
             performLayoutAndPlaceSurfacesLocked();
         }
-        Binder.restoreCallingIdentity(ident);
         return config;
     }
-    
+
     /*
      * The orientation is computed from non-application windows first. If none of
      * the non-application windows specify orientation, the orientation is computed from
-     * application tokens. 
+     * application tokens.
      * @see android.view.IWindowManager#updateOrientationFromAppTokens(
      * android.os.IBinder)
      */
@@ -2180,7 +2199,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             int req = computeForcedAppOrientationLocked();
-            
+
             if (req != mForcedAppOrientation) {
                 changed = true;
                 mForcedAppOrientation = req;
@@ -2188,7 +2207,7 @@
                 //action like disabling/enabling sensors etc.,
                 mPolicy.setCurrentOrientationLw(req);
             }
-            
+
             if (changed) {
                 changed = setRotationUncheckedLocked(
                         WindowManagerPolicy.USE_LAST_ROTATION,
@@ -2220,10 +2239,10 @@
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
-        
+
         return null;
     }
-    
+
     int computeForcedAppOrientationLocked() {
         int req = getOrientationFromWindowsLocked();
         if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
@@ -2231,39 +2250,39 @@
         }
         return req;
     }
-    
+
     public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppOrientation()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
-        
+
         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 int getAppOrientation(IApplicationToken token) {
         synchronized(mWindowMap) {
             AppWindowToken wtoken = findAppWindowToken(token.asBinder());
             if (wtoken == null) {
                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
             }
-            
+
             return wtoken.requestedOrientation;
         }
     }
-    
+
     public void setFocusedApp(IBinder token, boolean moveFocusNow) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setFocusedApp()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized(mWindowMap) {
@@ -2296,9 +2315,9 @@
     public void prepareAppTransition(int transit) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "prepareAppTransition()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
-        
+
         synchronized(mWindowMap) {
             if (DEBUG_APP_TRANSITIONS) Log.v(
                     TAG, "Prepare app transition: transit=" + transit
@@ -2306,6 +2325,14 @@
             if (!mDisplayFrozen) {
                 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
                     mNextAppTransition = transit;
+                } else if (transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
+                        && mNextAppTransition == WindowManagerPolicy.TRANSIT_TASK_CLOSE) {
+                    // Opening a new task always supersedes a close for the anim.
+                    mNextAppTransition = transit;
+                } else if (transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
+                        && mNextAppTransition == WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE) {
+                    // Opening a new activity always supersedes a close for the anim.
+                    mNextAppTransition = transit;
                 }
                 mAppTransitionReady = false;
                 mAppTransitionTimeout = false;
@@ -2321,13 +2348,13 @@
     public int getPendingAppTransition() {
         return mNextAppTransition;
     }
-    
+
     public void executeAppTransition() {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "executeAppTransition()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
-        
+
         synchronized(mWindowMap) {
             if (DEBUG_APP_TRANSITIONS) Log.v(
                     TAG, "Execute app transition: mNextAppTransition=" + mNextAppTransition);
@@ -2345,14 +2372,14 @@
             IBinder transferFrom, boolean createIfNeeded) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppStartingIcon()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         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);
@@ -2365,11 +2392,11 @@
             if (mDisplayFrozen) {
                 return;
             }
-            
+
             if (wtoken.startingData != null) {
                 return;
             }
-            
+
             if (transferFrom != null) {
                 AppWindowToken ttoken = findAppWindowToken(transferFrom);
                 if (ttoken != null) {
@@ -2385,7 +2412,7 @@
                                 "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;
@@ -2403,7 +2430,7 @@
                         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
@@ -2433,7 +2460,7 @@
                             wtoken.updateLayers();
                             ttoken.updateLayers();
                         }
-                        
+
                         updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
                         mLayoutNeeded = true;
                         performLayoutAndPlaceSurfacesLocked();
@@ -2463,7 +2490,7 @@
             if (!createIfNeeded) {
                 return;
             }
-            
+
             mStartingIconInTransition = true;
             wtoken.startingData = new StartingData(
                     pkg, theme, nonLocalizedLabel,
@@ -2479,7 +2506,7 @@
     public void setAppWillBeHidden(IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppWillBeHidden()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         AppWindowToken wtoken;
@@ -2493,7 +2520,7 @@
             wtoken.willBeHidden = true;
         }
     }
-    
+
     boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
             boolean visible, int transit, boolean performLayout) {
         boolean delayed = false;
@@ -2502,7 +2529,7 @@
             wtoken.clientHidden = !visible;
             wtoken.sendAppVisibilityToClients();
         }
-        
+
         wtoken.willBeHidden = false;
         if (wtoken.hidden == visible) {
             final int N = wtoken.allAppWindows.size();
@@ -2510,9 +2537,9 @@
             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;
@@ -2523,7 +2550,7 @@
                     delayed = runningAppAnimation = true;
                 }
             }
-            
+
             for (int i=0; i<N; i++) {
                 WindowState win = wtoken.allAppWindows.get(i);
                 if (win == wtoken.startingWindow) {
@@ -2533,7 +2560,7 @@
                 if (win.isAnimating()) {
                     delayed = true;
                 }
-                
+
                 //Log.i(TAG, "Window " + win + ": vis=" + win.isVisible());
                 //win.dump("  ");
                 if (visible) {
@@ -2568,11 +2595,11 @@
                     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);
@@ -2583,14 +2610,14 @@
         if (wtoken.animation != null) {
             delayed = true;
         }
-        
+
         return delayed;
     }
 
     public void setAppVisibility(IBinder token, boolean visible) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppVisibility()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         AppWindowToken wtoken;
@@ -2610,7 +2637,7 @@
                         + " 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) {
@@ -2619,7 +2646,7 @@
                     return;
                 }
                 wtoken.hiddenRequested = !visible;
-                
+
                 if (DEBUG_APP_TRANSITIONS) Log.v(
                         TAG, "Setting dummy animation on: " + wtoken);
                 wtoken.setDummyAnimation();
@@ -2631,7 +2658,7 @@
                     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
@@ -2647,7 +2674,7 @@
                 }
                 return;
             }
-            
+
             final long origId = Binder.clearCallingIdentity();
             setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_NONE, true);
             wtoken.updateReportedVisibilityLocked();
@@ -2688,7 +2715,7 @@
             }
         }
     }
-    
+
     public void startAppFreezingScreenLocked(AppWindowToken wtoken,
             int configChanges) {
         if (DEBUG_ORIENTATION) {
@@ -2716,11 +2743,11 @@
             }
         }
     }
-    
+
     public void startAppFreezingScreen(IBinder token, int configChanges) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppFreezingScreen()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized(mWindowMap) {
@@ -2728,7 +2755,7 @@
                 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);
@@ -2739,11 +2766,11 @@
             Binder.restoreCallingIdentity(origId);
         }
     }
-    
+
     public void stopAppFreezingScreen(IBinder token, boolean force) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppFreezingScreen()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized(mWindowMap) {
@@ -2758,11 +2785,11 @@
             Binder.restoreCallingIdentity(origId);
         }
     }
-    
+
     public void removeAppToken(IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "removeAppToken()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         AppWindowToken wtoken = null;
@@ -2807,7 +2834,7 @@
             } else {
                 Log.w(TAG, "Attempted to remove non-existing app token: " + token);
             }
-            
+
             if (!delayed && wtoken != null) {
                 wtoken.updateReportedVisibilityLocked();
             }
@@ -2841,13 +2868,13 @@
             Log.v(TAG, "  #" + i + ": " + mAppTokens.get(i).token);
         }
     }
-    
+
     void dumpWindowsLocked() {
         for (int i=mWindows.size()-1; i>=0; i--) {
             Log.v(TAG, "  #" + i + ": " + mWindows.get(i));
         }
     }
-    
+
     private int findWindowOffsetLocked(int tokenPos) {
         final int NW = mWindows.size();
 
@@ -2918,7 +2945,7 @@
         }
         return index;
     }
-    
+
     private final int reAddAppWindowsLocked(int index, WindowToken token) {
         final int NW = token.windows.size();
         for (int i=0; i<NW; i++) {
@@ -2930,7 +2957,7 @@
     public void moveAppToken(int index, IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "moveAppToken()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized(mWindowMap) {
@@ -2945,7 +2972,7 @@
             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();
@@ -3012,7 +3039,7 @@
     public void moveAppTokensToTop(List<IBinder> tokens) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "moveAppTokensToTop()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         final long origId = Binder.clearCallingIdentity();
@@ -3033,7 +3060,7 @@
     public void moveAppTokensToBottom(List<IBinder> tokens) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "moveAppTokensToBottom()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         final long origId = Binder.clearCallingIdentity();
@@ -3056,7 +3083,7 @@
     // -------------------------------------------------------------
     // Misc IWindowSession methods
     // -------------------------------------------------------------
-    
+
     public void disableKeyguard(IBinder token, String tag) {
         if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
             != PackageManager.PERMISSION_GRANTED) {
@@ -3110,17 +3137,17 @@
     public boolean inKeyguardRestrictedInputMode() {
         return mPolicy.inKeyguardRestrictedKeyInputMode();
     }
-    
+
     static float fixScale(float scale) {
         if (scale < 0) scale = 0;
         else if (scale > 20) scale = 20;
         return Math.abs(scale);
     }
-    
+
     public void setAnimationScale(int which, float scale) {
         if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
                 "setAnimationScale()")) {
-            return;
+            throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
         }
 
         if (scale < 0) scale = 0;
@@ -3130,15 +3157,15 @@
             case 0: mWindowAnimationScale = fixScale(scale); break;
             case 1: mTransitionAnimationScale = fixScale(scale); break;
         }
-        
+
         // Persist setting
         mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
     }
-    
+
     public void setAnimationScales(float[] scales) {
         if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
                 "setAnimationScale()")) {
-            return;
+            throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
         }
 
         if (scales != null) {
@@ -3149,11 +3176,11 @@
                 mTransitionAnimationScale = fixScale(scales[1]);
             }
         }
-        
+
         // Persist setting
         mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
     }
-    
+
     public float getAnimationScale(int which) {
         switch (which) {
             case 0: return mWindowAnimationScale;
@@ -3161,63 +3188,63 @@
         }
         return 0;
     }
-    
+
     public float[] getAnimationScales() {
         return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
     }
-    
+
     public int getSwitchState(int sw) {
         if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                 "getSwitchState()")) {
-            return -1;
+            throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
         return KeyInputQueue.getSwitchState(sw);
     }
-    
+
     public int getSwitchStateForDevice(int devid, int sw) {
         if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                 "getSwitchStateForDevice()")) {
-            return -1;
+            throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
         return KeyInputQueue.getSwitchState(devid, sw);
     }
-    
+
     public int getScancodeState(int sw) {
         if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                 "getScancodeState()")) {
-            return -1;
+            throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
         return KeyInputQueue.getScancodeState(sw);
     }
-    
+
     public int getScancodeStateForDevice(int devid, int sw) {
         if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                 "getScancodeStateForDevice()")) {
-            return -1;
+            throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
         return KeyInputQueue.getScancodeState(devid, sw);
     }
-    
+
     public int getKeycodeState(int sw) {
         if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                 "getKeycodeState()")) {
-            return -1;
+            throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
         return KeyInputQueue.getKeycodeState(sw);
     }
-    
+
     public int getKeycodeStateForDevice(int devid, int sw) {
         if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
                 "getKeycodeStateForDevice()")) {
-            return -1;
+            throw new SecurityException("Requires READ_INPUT_STATE permission");
         }
         return KeyInputQueue.getKeycodeState(devid, sw);
     }
-    
+
     public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
         return KeyInputQueue.hasKeys(keycodes, keyExists);
     }
-    
+
     public void enableScreenAfterBoot() {
         synchronized(mWindowMap) {
             if (mSystemBooted) {
@@ -3225,10 +3252,10 @@
             }
             mSystemBooted = true;
         }
-        
+
         performEnableScreen();
     }
-    
+
     public void enableScreenIfNeededLocked() {
         if (mDisplayEnabled) {
             return;
@@ -3238,7 +3265,7 @@
         }
         mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
     }
-    
+
     public void performEnableScreen() {
         synchronized(mWindowMap) {
             if (mDisplayEnabled) {
@@ -3247,7 +3274,7 @@
             if (!mSystemBooted) {
                 return;
             }
-            
+
             // Don't enable the screen until all existing windows
             // have been drawn.
             final int N = mWindows.size();
@@ -3257,7 +3284,7 @@
                     return;
                 }
             }
-            
+
             mDisplayEnabled = true;
             if (false) {
                 Log.i(TAG, "ENABLING SCREEN!");
@@ -3280,41 +3307,41 @@
                 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);
     }
-    
+
     public void setInTouchMode(boolean mode) {
         synchronized(mWindowMap) {
             mInTouchMode = mode;
         }
     }
 
-    public void setRotation(int rotation, 
+    public void setRotation(int rotation,
             boolean alwaysSendConfiguration, int animFlags) {
         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                 "setRotation()")) {
-            return;
+            throw new SecurityException("Requires SET_ORIENTATION permission");
         }
 
         setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
     }
-    
+
     public void setRotationUnchecked(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) {
@@ -3325,10 +3352,10 @@
             //update configuration ignoring orientation change
             sendNewConfiguration();
         }
-        
+
         Binder.restoreCallingIdentity(origId);
     }
-    
+
     public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
         boolean changed;
         if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
@@ -3342,9 +3369,9 @@
                 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, 
+            if (DEBUG_ORIENTATION) Log.v(TAG,
                     "Rotation changed to " + rotation
                     + " from " + mRotation
                     + " (forceApp=" + mForcedAppOrientation
@@ -3373,10 +3400,10 @@
                 }
             }
         } //end if changed
-        
+
         return changed;
     }
-    
+
     public int getRotation() {
         return mRotation;
     }
@@ -3388,14 +3415,17 @@
                 synchronized (mWindowMap) {
                     for (int i=0; i<mRotationWatchers.size(); i++) {
                         if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
-                            mRotationWatchers.remove(i);
+                            IRotationWatcher removed = mRotationWatchers.remove(i);
+                            if (removed != null) {
+                                removed.asBinder().unlinkToDeath(this, 0);
+                            }
                             i--;
                         }
                     }
                 }
             }
         };
-        
+
         synchronized (mWindowMap) {
             try {
                 watcher.asBinder().linkToDeath(dr, 0);
@@ -3403,7 +3433,7 @@
             } catch (RemoteException e) {
                 // Client died, no cleanup needed.
             }
-            
+
             return mRotation;
         }
     }
@@ -3419,7 +3449,7 @@
      * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
      */
     public boolean startViewServer(int port) {
-        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+        if (isSystemSecure()) {
             return false;
         }
 
@@ -3436,7 +3466,7 @@
                 try {
                     return mViewServer.start();
                 } catch (IOException e) {
-                    Log.w(TAG, "View server did not start");                    
+                    Log.w(TAG, "View server did not start");
                 }
             }
             return false;
@@ -3451,6 +3481,11 @@
         return false;
     }
 
+    private boolean isSystemSecure() {
+        return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
+                "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+    }
+
     /**
      * Stops the view server if it exists.
      *
@@ -3460,7 +3495,7 @@
      * @see com.android.server.ViewServer
      */
     public boolean stopViewServer() {
-        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+        if (isSystemSecure()) {
             return false;
         }
 
@@ -3482,7 +3517,7 @@
      * @see com.android.server.ViewServer
      */
     public boolean isViewServerRunning() {
-        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+        if (isSystemSecure()) {
             return false;
         }
 
@@ -3503,7 +3538,7 @@
      * @return False if an error occured, true otherwise.
      */
     boolean viewServerListWindows(Socket client) {
-        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+        if (isSystemSecure()) {
             return false;
         }
 
@@ -3570,7 +3605,7 @@
      *         not indicate whether the command itself was successful.
      */
     boolean viewServerWindowCommand(Socket client, String command, String parameters) {
-        if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+        if (isSystemSecure()) {
             return false;
         }
 
@@ -3660,13 +3695,13 @@
         } catch (RemoteException e) {
         }
     }
-    
+
     public Configuration computeNewConfiguration() {
         synchronized (mWindowMap) {
             return computeNewConfigurationLocked();
         }
     }
-    
+
     Configuration computeNewConfigurationLocked() {
         Configuration config = new Configuration();
         if (!computeNewConfigurationLocked(config)) {
@@ -3687,7 +3722,7 @@
         }
         return config;
     }
-    
+
     boolean computeNewConfigurationLocked(Configuration config) {
         if (mDisplay == null) {
             return false;
@@ -3702,12 +3737,46 @@
             orientation = Configuration.ORIENTATION_LANDSCAPE;
         }
         config.orientation = orientation;
+        
+        if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
+            // Note we only do this once because at this point we don't
+            // expect the screen to change in this way at runtime, and want
+            // to avoid all of this computation for every config change.
+            DisplayMetrics dm = new DisplayMetrics();
+            mDisplay.getMetrics(dm);
+            int longSize = dw;
+            int shortSize = dh;
+            if (longSize < shortSize) {
+                int tmp = longSize;
+                longSize = shortSize;
+                shortSize = tmp;
+            }
+            longSize = (int)(longSize/dm.density);
+            shortSize = (int)(shortSize/dm.density);
+            
+            // These semi-magic numbers define our compatibility modes for
+            // applications with different screens.  Don't change unless you
+            // make sure to test lots and lots of apps!
+            if (longSize < 470) {
+                // This is shorter than an HVGA normal density screen (which
+                // is 480 pixels on its long side).
+                screenLayout = Configuration.SCREENLAYOUT_SMALL;
+            } else if (longSize > 490 && shortSize > 330) {
+                // This is larger than an HVGA normal density screen (which
+                // is 480x320 pixels).
+                screenLayout = Configuration.SCREENLAYOUT_LARGE;
+            } else {
+                screenLayout = Configuration.SCREENLAYOUT_NORMAL;
+            }
+        }
+        config.screenLayout = screenLayout;
+        
         config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
         config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
         mPolicy.adjustConfigurationLw(config);
         return true;
     }
-    
+
     // -------------------------------------------------------------
     // Input Events and Focus Management
     // -------------------------------------------------------------
@@ -3771,15 +3840,15 @@
     /**
      * @return Returns true if event was dispatched, false if it was dropped for any reason
      */
-    private boolean dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
+    private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
         if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Log.v(TAG,
                 "dispatchPointer " + ev);
 
         Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
-                ev, true, false);
-        
+                ev, true, false, pid, uid);
+
         int action = ev.getAction();
-        
+
         if (action == MotionEvent.ACTION_UP) {
             // let go of our target
             mKeyWaiter.mMotionTarget = null;
@@ -3801,20 +3870,20 @@
                 mQueue.recycleEvent(qev);
             }
             ev.recycle();
-            return false;
+            return INJECT_FAILED;
         }
         if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
             if (qev != null) {
                 mQueue.recycleEvent(qev);
             }
             ev.recycle();
-            return true;
+            return INJECT_SUCCEEDED;
         }
-        
+
         WindowState target = (WindowState)targetObj;
-        
+
         final long eventTime = ev.getEventTime();
-        
+
         //Log.i(TAG, "Sending " + ev + " to " + target);
 
         if (uid != 0 && uid != target.mSession.mUid) {
@@ -3828,11 +3897,11 @@
                     mQueue.recycleEvent(qev);
                 }
                 ev.recycle();
-                return false;
+                return INJECT_NO_PERMISSION;
             }
         }
-        
-        if ((target.mAttrs.flags & 
+
+        if ((target.mAttrs.flags &
                         WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
             //target wants to ignore fat touch events
             boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
@@ -3859,7 +3928,7 @@
                     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 
+                        //a valid down,  invalid move, more moves. want to ignore till up
                         returnFlag = true;
                     } else if(cheekPress) {
                         //valid down followed by invalid moves
@@ -3878,7 +3947,7 @@
                     mQueue.recycleEvent(qev);
                 }
                 ev.recycle();
-                return false;
+                return INJECT_FAILED;
             }
         } //end if target
 
@@ -3944,7 +4013,7 @@
                 mKeyWaiter.bindTargetWindowLocked(target);
             }
         }
-        
+
         // finally offset the event to the target's coordinate system and
         // dispatch the event.
         try {
@@ -3952,7 +4021,7 @@
                 Log.v(TAG, "Delivering pointer " + qev + " to " + target);
             }
             target.mClient.dispatchPointer(ev, eventTime);
-            return true;
+            return INJECT_SUCCEEDED;
         } catch (android.os.RemoteException e) {
             Log.i(TAG, "WINDOW DIED during motion dispatch: " + target);
             mKeyWaiter.mMotionTarget = null;
@@ -3963,36 +4032,36 @@
                 // removed.
             }
         }
-        return false;
+        return INJECT_FAILED;
     }
-    
+
     /**
      * @return Returns true if event was dispatched, false if it was dropped for any reason
      */
-    private boolean dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
+    private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
         if (DEBUG_INPUT) Log.v(
                 TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
-        
+
         Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
-                ev, false, false);
+                ev, false, false, pid, uid);
         if (focusObj == null) {
             Log.w(TAG, "No focus window, dropping trackball: " + ev);
             if (qev != null) {
                 mQueue.recycleEvent(qev);
             }
             ev.recycle();
-            return false;
+            return INJECT_FAILED;
         }
         if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
             if (qev != null) {
                 mQueue.recycleEvent(qev);
             }
             ev.recycle();
-            return true;
+            return INJECT_SUCCEEDED;
         }
-        
+
         WindowState focus = (WindowState)focusObj;
-        
+
         if (uid != 0 && uid != focus.mSession.mUid) {
             if (mContext.checkPermission(
                     android.Manifest.permission.INJECT_EVENTS, pid, uid)
@@ -4004,12 +4073,12 @@
                     mQueue.recycleEvent(qev);
                 }
                 ev.recycle();
-                return false;
+                return INJECT_NO_PERMISSION;
             }
         }
-        
+
         final long eventTime = ev.getEventTime();
-        
+
         synchronized(mWindowMap) {
             if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
                 mKeyWaiter.bindTargetWindowLocked(focus,
@@ -4021,10 +4090,10 @@
                 mKeyWaiter.bindTargetWindowLocked(focus);
             }
         }
-        
+
         try {
             focus.mClient.dispatchTrackball(ev, eventTime);
-            return true;
+            return INJECT_SUCCEEDED;
         } catch (android.os.RemoteException e) {
             Log.i(TAG, "WINDOW DIED during key dispatch: " + focus);
             try {
@@ -4034,28 +4103,28 @@
                 // removed.
             }
         }
-        
-        return false;
+
+        return INJECT_FAILED;
     }
-    
+
     /**
      * @return Returns true if event was dispatched, false if it was dropped for any reason
      */
-    private boolean dispatchKey(KeyEvent event, int pid, int uid) {
+    private int dispatchKey(KeyEvent event, int pid, int uid) {
         if (DEBUG_INPUT) Log.v(TAG, "Dispatch key: " + event);
 
         Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
-                null, false, false);
+                null, false, false, pid, uid);
         if (focusObj == null) {
             Log.w(TAG, "No focus window, dropping: " + event);
-            return false;
+            return INJECT_FAILED;
         }
         if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
-            return true;
+            return INJECT_SUCCEEDED;
         }
-        
+
         WindowState focus = (WindowState)focusObj;
-        
+
         if (DEBUG_INPUT) Log.v(
             TAG, "Dispatching to " + focus + ": " + event);
 
@@ -4066,10 +4135,10 @@
                 Log.w(TAG, "Permission denied: injecting key event from pid "
                         + pid + " uid " + uid + " to window " + focus
                         + " owned by uid " + focus.mSession.mUid);
-                return false;
+                return INJECT_NO_PERMISSION;
             }
         }
-        
+
         synchronized(mWindowMap) {
             mKeyWaiter.bindTargetWindowLocked(focus);
         }
@@ -4077,14 +4146,14 @@
         // 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;
+            return INJECT_SUCCEEDED;
         } catch (android.os.RemoteException e) {
             Log.i(TAG, "WINDOW DIED during key dispatch: " + focus);
             try {
@@ -4094,14 +4163,14 @@
                 // removed.
             }
         }
-        
-        return false;
+
+        return INJECT_FAILED;
     }
-    
+
     public void pauseKeyDispatching(IBinder _token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "pauseKeyDispatching()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized (mWindowMap) {
@@ -4115,7 +4184,7 @@
     public void resumeKeyDispatching(IBinder _token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "resumeKeyDispatching()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized (mWindowMap) {
@@ -4129,18 +4198,18 @@
     public void setEventDispatching(boolean enabled) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "resumeKeyDispatching()")) {
-            return;
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized (mWindowMap) {
             mKeyWaiter.setEventDispatchingLocked(enabled);
         }
     }
-    
+
     /**
      * Injects a keystroke event into the UI.
-     * 
-     * @param ev A motion event describing the keystroke action.  (Be sure to use 
+     *
+     * @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
@@ -4162,47 +4231,80 @@
         KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
                 deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
 
-        boolean result = dispatchKey(newEvent, Binder.getCallingPid(), Binder.getCallingUid());
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        final int result = dispatchKey(newEvent, pid, uid);
         if (sync) {
-            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
+            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
         }
-        return result;
+        Binder.restoreCallingIdentity(ident);
+        switch (result) {
+            case INJECT_NO_PERMISSION:
+                throw new SecurityException(
+                        "Injecting to another application requires INJECT_EVENT permission");
+            case INJECT_SUCCEEDED:
+                return true;
+        }
+        return false;
     }
 
     /**
      * 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 
+     *
+     * @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
      */
     public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
-        boolean result = dispatchPointer(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        final int result = dispatchPointer(null, ev, pid, uid);
         if (sync) {
-            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
+            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
         }
-        return result;        
+        Binder.restoreCallingIdentity(ident);
+        switch (result) {
+            case INJECT_NO_PERMISSION:
+                throw new SecurityException(
+                        "Injecting to another application requires INJECT_EVENT permission");
+            case INJECT_SUCCEEDED:
+                return true;
+        }
+        return false;
     }
-    
+
     /**
      * 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 
+     *
+     * @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
      */
     public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
-        boolean result = dispatchTrackball(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        final int result = dispatchTrackball(null, ev, pid, uid);
         if (sync) {
-            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
+            mKeyWaiter.waitForNextEventTarget(null, null, null, false, true, pid, uid);
         }
-        return result;
+        Binder.restoreCallingIdentity(ident);
+        switch (result) {
+            case INJECT_NO_PERMISSION:
+                throw new SecurityException(
+                        "Injecting to another application requires INJECT_EVENT permission");
+            case INJECT_SUCCEEDED:
+                return true;
+        }
+        return false;
     }
-    
+
     private WindowState getFocusedWindow() {
         synchronized (mWindowMap) {
             return getFocusedWindowLocked();
@@ -4212,7 +4314,7 @@
     private WindowState getFocusedWindowLocked() {
         return mCurrentFocus;
     }
-    
+
     /**
      * This class holds the state for dispatching key events.  This state
      * is protected by the KeyWaiter instance, NOT by the window lock.  You
@@ -4234,7 +4336,7 @@
             private boolean wasFrozen;
             private boolean focusPaused;
             private WindowState curFocus;
-            
+
             DispatchState(KeyEvent theEvent, WindowState theFocus) {
                 focus = theFocus;
                 event = theEvent;
@@ -4256,7 +4358,7 @@
                     focusPaused = theFocus.mToken.paused;
                 }
             }
-            
+
             public String toString() {
                 return "{{" + event + " to " + focus + " @ " + time
                         + " lw=" + lastWin + " lb=" + lastBinder
@@ -4275,10 +4377,10 @@
         public static final int RETURN_NOTHING = 0;
         public static final int RETURN_PENDING_POINTER = 1;
         public static final int RETURN_PENDING_TRACKBALL = 2;
-        
+
         final Object SKIP_TARGET_TOKEN = new Object();
         final Object CONSUMED_EVENT_TOKEN = new Object();
-        
+
         private WindowState mLastWin = null;
         private IBinder mLastBinder = null;
         private boolean mFinished = true;
@@ -4286,10 +4388,10 @@
         private boolean mEventDispatching = true;
         private long mTimeToSwitch = 0;
         /* package */ boolean mWasFrozen = false;
-        
+
         // Target of Motion events
         WindowState mMotionTarget;
-        
+
         // Windows above the target who would like to receive an "outside"
         // touch event for any down events outside of them.
         WindowState mOutsideTouchTargets;
@@ -4301,7 +4403,7 @@
          */
         Object waitForNextEventTarget(KeyEvent nextKey, QueuedEvent qev,
                 MotionEvent nextMotion, boolean isPointerEvent,
-                boolean failIfTimeout) {
+                boolean failIfTimeout, int callingPid, int callingUid) {
             long startTime = SystemClock.uptimeMillis();
             long keyDispatchingTimeout = 5 * 1000;
             long waitedFor = 0;
@@ -4319,7 +4421,7 @@
                         ", mLastWin=" + mLastWin);
                 if (targetIsNew) {
                     Object target = findTargetWindow(nextKey, qev, nextMotion,
-                            isPointerEvent);
+                            isPointerEvent, callingPid, callingUid);
                     if (target == SKIP_TARGET_TOKEN) {
                         // The user has pressed a special key, and we are
                         // dropping all pending events before it.
@@ -4334,9 +4436,9 @@
                     }
                     targetWin = (WindowState)target;
                 }
-                
+
                 AppWindowToken targetApp = null;
-                
+
                 // Now: is it okay to send the next event to this window?
                 synchronized (this) {
                     // First: did we come here based on the last window not
@@ -4345,7 +4447,7 @@
                     if (!targetIsNew && mLastWin == null) {
                         continue;
                     }
-                    
+
                     // We never dispatch events if not finished with the
                     // last one, or the display is frozen.
                     if (mFinished && !mDisplayFrozen) {
@@ -4364,7 +4466,7 @@
                             if (targetIsNew && !targetWin.mToken.paused) {
                                 return targetWin;
                             }
-                        
+
                         // If we didn't find a target window, and there is no
                         // focused app window, then just eat the events.
                         } else if (mFocusedApp == null) {
@@ -4374,7 +4476,7 @@
                             return null;
                         }
                     }
-                    
+
                     if (DEBUG_INPUT) Log.v(
                             TAG, "Waiting for last key in " + mLastBinder
                             + " target=" + targetWin
@@ -4385,10 +4487,10 @@
                             + (targetWin != null ? targetWin.mToken.paused : false)
                             + " mFocusedApp=" + mFocusedApp
                             + " mCurrentFocus=" + mCurrentFocus);
-                    
+
                     targetApp = targetWin != null
                             ? targetWin.mAppToken : mFocusedApp;
-                    
+
                     long curTimeout = keyDispatchingTimeout;
                     if (mTimeToSwitch != 0) {
                         long now = SystemClock.uptimeMillis();
@@ -4404,7 +4506,7 @@
                             curTimeout = switchTimeout;
                         }
                     }
-                    
+
                     try {
                         // after that continue
                         // processing keys, so we don't get stuck.
@@ -4468,7 +4570,7 @@
                     synchronized (this) {
                         if (abort && (mLastWin == targetWin || targetWin == null)) {
                             mFinished = true;
-                            if (mLastWin != null) { 
+                            if (mLastWin != null) {
                                 if (DEBUG_INPUT) Log.v(TAG,
                                         "Window " + mLastWin +
                                         " timed out on key input");
@@ -4493,41 +4595,56 @@
                 }
             }
         }
-        
+
         Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
-                MotionEvent nextMotion, boolean isPointerEvent) {
+                MotionEvent nextMotion, boolean isPointerEvent,
+                int callingPid, int callingUid) {
             mOutsideTouchTargets = null;
-            
+
             if (nextKey != null) {
                 // Find the target window for a normal key event.
                 final int keycode = nextKey.getKeyCode();
                 final int repeatCount = nextKey.getRepeatCount();
                 final boolean down = nextKey.getAction() != KeyEvent.ACTION_UP;
                 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(keycode);
+                
                 if (!dispatch) {
-                    mPolicy.interceptKeyTi(null, keycode,
-                            nextKey.getMetaState(), down, repeatCount);
+                    if (callingUid == 0 ||
+                            mContext.checkPermission(
+                                    android.Manifest.permission.INJECT_EVENTS,
+                                    callingPid, callingUid)
+                                    == PackageManager.PERMISSION_GRANTED) {
+                        mPolicy.interceptKeyTi(null, keycode,
+                                nextKey.getMetaState(), down, repeatCount);
+                    }
                     Log.w(TAG, "Event timeout during app switch: dropping "
                             + nextKey);
                     return SKIP_TARGET_TOKEN;
                 }
-                
+
                 // System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
-                
+
                 WindowState focus = null;
                 synchronized(mWindowMap) {
                     focus = getFocusedWindowLocked();
                 }
-                
+
                 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
-                
-                if (mPolicy.interceptKeyTi(focus,
-                        keycode, nextKey.getMetaState(), down, repeatCount)) {
-                    return CONSUMED_EVENT_TOKEN;
+
+                if (callingUid == 0 ||
+                        (focus != null && callingUid == focus.mSession.mUid) ||
+                        mContext.checkPermission(
+                                android.Manifest.permission.INJECT_EVENTS,
+                                callingPid, callingUid)
+                                == PackageManager.PERMISSION_GRANTED) {
+                    if (mPolicy.interceptKeyTi(focus,
+                            keycode, nextKey.getMetaState(), down, repeatCount)) {
+                        return CONSUMED_EVENT_TOKEN;
+                    }
                 }
-                
+
                 return focus;
-                
+
             } else if (!isPointerEvent) {
                 boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
                 if (!dispatch) {
@@ -4535,20 +4652,20 @@
                             + nextMotion);
                     return SKIP_TARGET_TOKEN;
                 }
-                
+
                 WindowState focus = null;
                 synchronized(mWindowMap) {
                     focus = getFocusedWindowLocked();
                 }
-                
+
                 wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
                 return focus;
             }
-            
+
             if (nextMotion == null) {
                 return SKIP_TARGET_TOKEN;
             }
-            
+
             boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
                     KeyEvent.KEYCODE_UNKNOWN);
             if (!dispatch) {
@@ -4556,18 +4673,18 @@
                         + nextMotion);
                 return SKIP_TARGET_TOKEN;
             }
-            
+
             // Find the target window for a pointer event.
             int action = nextMotion.getAction();
             final float xf = nextMotion.getX();
             final float yf = nextMotion.getY();
             final long eventTime = nextMotion.getEventTime();
-            
+
             final boolean screenWasOff = qev != null
                     && (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
-            
+
             WindowState target = null;
-            
+
             synchronized(mWindowMap) {
                 synchronized (this) {
                     if (action == MotionEvent.ACTION_DOWN) {
@@ -4580,12 +4697,12 @@
                                     + mMotionTarget);
                             mMotionTarget = null;
                         }
-                        
+
                         // ACTION_DOWN is special, because we need to lock next events to
                         // the window we'll land onto.
                         final int x = (int)xf;
                         final int y = (int)yf;
-    
+
                         final ArrayList windows = mWindows;
                         final int N = windows.size();
                         WindowState topErrWindow = null;
@@ -4646,7 +4763,7 @@
                                 }
                                 break;
                             }
-                            
+
                             if ((flags & WindowManager.LayoutParams
                                     .FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
                                 child.mNextOutsideTouch = mOutsideTouchTargets;
@@ -4663,18 +4780,18 @@
                             mMotionTarget = null;
                         }
                     }
-                    
+
                     target = mMotionTarget;
                 }
             }
-            
+
             wakeupIfNeeded(target, eventType(nextMotion));
-            
+
             // Pointer events are a little different -- if there isn't a
             // target found for any event, then just drop it.
             return target != null ? target : SKIP_TARGET_TOKEN;
         }
-        
+
         boolean checkShouldDispatchKey(int keycode) {
             synchronized (this) {
                 if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
@@ -4688,14 +4805,14 @@
                 return true;
             }
         }
-        
+
         void bindTargetWindowLocked(WindowState win,
                 int pendingWhat, QueuedEvent pendingMotion) {
             synchronized (this) {
                 bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
             }
         }
-        
+
         void bindTargetWindowLocked(WindowState win) {
             synchronized (this) {
                 bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
@@ -4713,7 +4830,7 @@
                     releasePendingPointerLocked(s);
                     s.mPendingPointerMove = pendingMotion;
                     s.mPendingPointerWindow = win;
-                    if (DEBUG_INPUT) Log.v(TAG, 
+                    if (DEBUG_INPUT) Log.v(TAG,
                             "bindTargetToWindow " + s.mPendingPointerMove);
                 } else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
                     releasePendingTrackballLocked(s);
@@ -4722,7 +4839,7 @@
                 }
             }
         }
-        
+
         void releasePendingPointerLocked(Session s) {
             if (DEBUG_INPUT) Log.v(TAG,
                     "releasePendingPointer " + s.mPendingPointerMove);
@@ -4731,14 +4848,14 @@
                 s.mPendingPointerMove = null;
             }
         }
-        
+
         void releasePendingTrackballLocked(Session s) {
             if (s.mPendingTrackballMove != null) {
                 mQueue.recycleEvent(s.mPendingTrackballMove);
                 s.mPendingTrackballMove = null;
             }
         }
-        
+
         MotionEvent finishedKey(Session session, IWindow client, boolean force,
                 int returnWhat) {
             if (DEBUG_INPUT) Log.v(
@@ -4767,7 +4884,7 @@
                     session.mPendingTrackballMove = null;
                     session.mPendingTrackballWindow = null;
                 }
-                
+
                 if (mLastBinder == client.asBinder()) {
                     if (DEBUG_INPUT) Log.v(
                         TAG, "finishedKey: last paused="
@@ -4783,7 +4900,7 @@
                         notifyAll();
                     }
                 }
-                
+
                 if (qev != null) {
                     MotionEvent res = (MotionEvent)qev.event;
                     if (DEBUG_INPUT) Log.v(TAG,
@@ -4803,7 +4920,7 @@
                 notifyAll();
             }
         }
-        
+
         void handleNewWindowLocked(WindowState newWindow) {
             if (!newWindow.canReceiveKeys()) {
                 return;
@@ -4904,7 +5021,7 @@
                 notifyAll();
             }
         }
-        
+
         void appSwitchComing() {
             synchronized (this) {
                 // Don't wait for more than .5 seconds for app to finish
@@ -4917,13 +5034,13 @@
                 notifyAll();
             }
         }
-        
+
         private final void doFinishedKeyLocked(boolean doRecycle) {
             if (mLastWin != null) {
                 releasePendingPointerLocked(mLastWin.mSession);
                 releasePendingTrackballLocked(mLastWin.mSession);
             }
-            
+
             if (mLastWin == null || !mLastWin.mToken.paused
                 || !mLastWin.isVisibleLw()) {
                 // If the current window has been paused, we aren't -really-
@@ -4939,7 +5056,7 @@
     private class KeyQ extends KeyInputQueue
             implements KeyInputQueue.FilterCallback {
         PowerManager.WakeLock mHoldingScreen;
-        
+
         KeyQ() {
             super(mContext);
             PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
@@ -4953,7 +5070,7 @@
             if (mPolicy.preprocessInputEventTq(event)) {
                 return true;
             }
-            
+
             switch (event.type) {
                 case RawInputEvent.EV_KEY: {
                     // XXX begin hack
@@ -4973,11 +5090,11 @@
                         }
                     }
                     // XXX end hack
-                    
+
                     boolean screenIsOff = !mPowerManager.screenIsOn();
                     boolean screenIsDim = !mPowerManager.screenIsBright();
                     int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
-                    
+
                     if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
                         mPowerManager.goToSleep(event.when);
                     }
@@ -4992,7 +5109,7 @@
                         mPowerManager.userActivity(event.when, false,
                                 LocalPowerManager.BUTTON_EVENT, false);
                     }
-                    
+
                     if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
                         if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
                             filterQueue(this);
@@ -5003,7 +5120,7 @@
                         return false;
                     }
                 }
-                    
+
                 case RawInputEvent.EV_REL: {
                     boolean screenIsOff = !mPowerManager.screenIsOn();
                     boolean screenIsDim = !mPowerManager.screenIsBright();
@@ -5020,7 +5137,7 @@
                     }
                     return true;
                 }
-                
+
                 case RawInputEvent.EV_ABS: {
                     boolean screenIsOff = !mPowerManager.screenIsOn();
                     boolean screenIsDim = !mPowerManager.screenIsBright();
@@ -5037,7 +5154,7 @@
                     }
                     return true;
                 }
-                    
+
                 default:
                     return true;
             }
@@ -5057,7 +5174,7 @@
                     return FILTER_KEEP;
             }
         }
-        
+
         /**
          * Must be called with the main window manager lock held.
          */
@@ -5078,11 +5195,11 @@
         mSafeMode = mPolicy.detectSafeMode();
         return mSafeMode;
     }
-    
+
     public void systemReady() {
         mPolicy.systemReady();
     }
-    
+
     private final class InputDispatcherThread extends Thread {
         // Time to wait when there is nothing to do: 9999 seconds.
         static final int LONG_WAIT=9999*1000;
@@ -5090,7 +5207,7 @@
         public InputDispatcherThread() {
             super("InputDispatcher");
         }
-        
+
         @Override
         public void run() {
             while (true) {
@@ -5101,11 +5218,11 @@
                 }
             }
         }
-        
+
         private void process() {
             android.os.Process.setThreadPriority(
                     android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
-            
+
             // The last key event we saw
             KeyEvent lastKey = null;
 
@@ -5113,12 +5230,12 @@
             long lastKeyTime = SystemClock.uptimeMillis();
             long nextKeyTime = lastKeyTime+LONG_WAIT;
 
-            // How many successive repeats we generated 
+            // How many successive repeats we generated
             int keyRepeatCount = 0;
 
             // Need to report that configuration has changed?
             boolean configChanged = false;
-            
+
             while (true) {
                 long curTime = SystemClock.uptimeMillis();
 
@@ -5199,14 +5316,14 @@
                                 mQueue.recycleEvent(ev);
                             break;
                         }
-                        
+
                     } else if (configChanged) {
                         configChanged = false;
                         sendNewConfiguration();
-                        
+
                     } else if (lastKey != null) {
                         curTime = SystemClock.uptimeMillis();
-                        
+
                         // Timeout occurred while key was down.  If it is at or
                         // past the key repeat time, dispatch the repeat.
                         if (DEBUG_INPUT) Log.v(
@@ -5215,7 +5332,7 @@
                         if (curTime < nextKeyTime) {
                             continue;
                         }
-    
+
                         lastKeyTime = nextKeyTime;
                         nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
                         keyRepeatCount++;
@@ -5223,14 +5340,14 @@
                             TAG, "Key repeat: count=" + keyRepeatCount
                             + ", next @ " + nextKeyTime);
                         dispatchKey(KeyEvent.changeTimeRepeat(lastKey, curTime, keyRepeatCount), 0, 0);
-                        
+
                     } else {
                         curTime = SystemClock.uptimeMillis();
-                        
+
                         lastKeyTime = curTime;
                         nextKeyTime = curTime + LONG_WAIT;
                     }
-                    
+
                 } catch (Exception e) {
                     Log.e(TAG,
                         "Input thread received uncaught exception: " + e, e);
@@ -5253,14 +5370,14 @@
         SurfaceSession mSurfaceSession;
         int mNumWindow = 0;
         boolean mClientDead = false;
-        
+
         /**
          * Current pointer move event being dispatched to client window...  must
          * hold key lock to access.
          */
         QueuedEvent mPendingPointerMove;
         WindowState mPendingPointerWindow;
-        
+
         /**
          * Current trackball move event being dispatched to client window...  must
          * hold key lock to access.
@@ -5280,7 +5397,7 @@
             sb.append(mUid);
             sb.append("}");
             mStringName = sb.toString();
-            
+
             synchronized (mWindowMap) {
                 if (mInputMethodManager == null && mHaveInputMethods) {
                     IBinder b = ServiceManager.getService(
@@ -5311,7 +5428,7 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
-        
+
         @Override
         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
                 throws RemoteException {
@@ -5336,6 +5453,7 @@
             } catch (RemoteException e) {
             }
             synchronized(mWindowMap) {
+                mClient.asBinder().unlinkToDeath(this, 0);
                 mClientDead = true;
                 killSessionLocked();
             }
@@ -5345,11 +5463,11 @@
                 int viewVisibility, Rect outContentInsets) {
             return addWindow(this, window, attrs, viewVisibility, outContentInsets);
         }
-        
+
         public void remove(IWindow window) {
             removeWindow(this, window);
         }
-        
+
         public int relayout(IWindow window, WindowManager.LayoutParams attrs,
                 int requestedWidth, int requestedHeight, int viewFlags,
                 boolean insetsPending, Rect outFrame, Rect outContentInsets,
@@ -5358,21 +5476,21 @@
                     requestedWidth, requestedHeight, viewFlags, insetsPending,
                     outFrame, outContentInsets, outVisibleInsets, outSurface);
         }
-        
+
         public void setTransparentRegion(IWindow window, Region region) {
             setTransparentRegionWindow(this, window, region);
         }
-        
+
         public void setInsets(IWindow window, int touchableInsets,
                 Rect contentInsets, Rect visibleInsets) {
             setInsetsWindow(this, window, touchableInsets, contentInsets,
                     visibleInsets);
         }
-        
+
         public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
             getWindowDisplayFrame(this, window, outDisplayFrame);
         }
-        
+
         public void finishDrawing(IWindow window) {
             if (localLOGV) Log.v(
                 TAG, "IWindow finishDrawing called for " + window);
@@ -5392,7 +5510,7 @@
             return mKeyWaiter.finishedKey(this, window, false,
                     KeyWaiter.RETURN_PENDING_POINTER);
         }
-        
+
         public MotionEvent getPendingTrackballMove(IWindow window) {
             if (localLOGV) Log.v(
                     TAG, "IWindow getPendingMotionEvent called for " + window);
@@ -5424,7 +5542,7 @@
                 }
             }
         }
-        
+
         void windowAddedLocked() {
             if (mSurfaceSession == null) {
                 if (localLOGV) Log.v(
@@ -5439,7 +5557,7 @@
             mNumWindow--;
             killSessionLocked();
         }
-    
+
         void killSessionLocked() {
             if (mNumWindow <= 0 && mClientDead) {
                 mSessions.remove(this);
@@ -5458,7 +5576,7 @@
                 }
             }
         }
-        
+
         void dump(PrintWriter pw, String prefix) {
             pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
                     pw.print(" mClientDead="); pw.print(mClientDead);
@@ -5519,11 +5637,11 @@
         boolean mHaveFrame;
 
         WindowState mNextOutsideTouch;
-        
+
         // Actual frame shown on-screen (may be modified by animation)
         final Rect mShownFrame = new Rect();
         final Rect mLastShownFrame = new Rect();
-        
+
         /**
          * Insets that determine the actually visible area
          */
@@ -5543,19 +5661,19 @@
          * given internal insets before laying out other windows based on it.
          */
         boolean mGivenInsetsPending;
-        
+
         /**
          * These are the content insets that were given during layout for
          * this window, to be applied to windows behind it.
          */
         final Rect mGivenContentInsets = new Rect();
-        
+
         /**
          * These are the visible insets that were given during layout for
          * this window, to be applied to windows behind it.
          */
         final Rect mGivenVisibleInsets = new Rect();
-        
+
         /**
          * Flag indicating whether the touchable region should be adjusted by
          * the visible insets; if false the area outside the visible insets is
@@ -5563,7 +5681,7 @@
          * tests.
          */
         int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
-        
+
         // Current transformation being applied.
         float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
         float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
@@ -5602,7 +5720,7 @@
         // where we don't yet have a surface, but should have one soon, so
         // we can give the window focus before waiting for the relayout.
         boolean mRelayoutCalled;
-        
+
         // This is set after the Surface has been created but before the
         // window has been drawn.  During this time the surface is hidden.
         boolean mDrawPending;
@@ -5617,7 +5735,7 @@
         // to delay showing the surface until all windows in a token are ready
         // to be shown.
         boolean mReadyToShow;
-        
+
         // Set when the window has been shown in the screen the first time.
         boolean mHasDrawn;
 
@@ -5626,17 +5744,17 @@
 
         // Currently on the mDestroySurface list?
         boolean mDestroying;
-        
+
         // Completely remove from window manager after exit animation?
         boolean mRemoveOnExit;
 
         // Set when the orientation is changing and this window has not yet
         // been updated for the new orientation.
         boolean mOrientationChanging;
-        
+
         // Is this window now (or just being) removed?
         boolean mRemoved;
-        
+
         WindowState(Session s, IWindow c, WindowToken token,
                WindowState attachedWindow, WindowManager.LayoutParams a,
                int viewVisibility) {
@@ -5662,7 +5780,7 @@
                 return;
             }
             mDeathRecipient = deathRecipient;
-            
+
             if ((mAttrs.type >= FIRST_SUB_WINDOW &&
                     mAttrs.type <= LAST_SUB_WINDOW)) {
                 // The multiplier here is to reserve space for multiple
@@ -5738,7 +5856,7 @@
                 w = mAttrs.width == mAttrs.FILL_PARENT ? pw : mRequestedWidth;
                 h = mAttrs.height== mAttrs.FILL_PARENT ? ph : mRequestedHeight;
             }
-            
+
             final Rect container = mContainingFrame;
             container.set(pf);
 
@@ -5747,12 +5865,12 @@
 
             final Rect content = mContentFrame;
             content.set(cf);
-            
+
             final Rect visible = mVisibleFrame;
             visible.set(vf);
-            
+
             final Rect frame = mFrame;
-            
+
             //System.out.println("In: w=" + w + " h=" + h + " container=" +
             //                   container + " x=" + mAttrs.x + " y=" + mAttrs.y);
 
@@ -5764,7 +5882,7 @@
 
             // Now make sure the window fits in the overall display.
             Gravity.applyDisplay(mAttrs.gravity, df, frame);
-            
+
             // Make sure the content and visible frames are inside of the
             // final window frame.
             if (content.left < frame.left) content.left = frame.left;
@@ -5775,19 +5893,19 @@
             if (visible.top < frame.top) visible.top = frame.top;
             if (visible.right > frame.right) visible.right = frame.right;
             if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
-            
+
             final Rect contentInsets = mContentInsets;
             contentInsets.left = content.left-frame.left;
             contentInsets.top = content.top-frame.top;
             contentInsets.right = frame.right-content.right;
             contentInsets.bottom = frame.bottom-content.bottom;
-            
+
             final Rect visibleInsets = mVisibleInsets;
             visibleInsets.left = visible.left-frame.left;
             visibleInsets.top = visible.top-frame.top;
             visibleInsets.right = frame.right-visible.right;
             visibleInsets.bottom = frame.bottom-visible.bottom;
-            
+
             if (localLOGV) {
                 //if ("com.google.android.youtube".equals(mAttrs.packageName)
                 //        && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
@@ -5800,7 +5918,7 @@
                 //}
             }
         }
-        
+
         public Rect getFrameLw() {
             return mFrame;
         }
@@ -5828,11 +5946,11 @@
         public Rect getGivenContentInsetsLw() {
             return mGivenContentInsets;
         }
-        
+
         public Rect getGivenVisibleInsetsLw() {
             return mGivenVisibleInsets;
         }
-        
+
         public WindowManager.LayoutParams getAttrs() {
             return mAttrs;
         }
@@ -5840,7 +5958,7 @@
         public int getSurfaceLayer() {
             return mLayer;
         }
-        
+
         public IApplicationToken getAppToken() {
             return mAppToken != null ? mAppToken.appToken : null;
         }
@@ -5874,7 +5992,7 @@
                 mAnimation = null;
             }
         }
-        
+
         Surface createSurfaceLocked() {
             if (mSurface == null) {
                 mDrawPending = true;
@@ -5914,7 +6032,7 @@
 
                 try {
                     mSurface = new Surface(
-                            mSession.mSurfaceSession, mSession.mPid, 
+                            mSession.mSurfaceSession, mSession.mPid,
                             0, w, h, mAttrs.format, flags);
                 } catch (Surface.OutOfResourcesException e) {
                     Log.w(TAG, "OutOfResourcesException creating surface");
@@ -5924,7 +6042,7 @@
                     Log.e(TAG, "Exception creating surface", e);
                     return null;
                 }
-                
+
                 if (localLOGV) Log.v(
                     TAG, "Got surface: " + mSurface
                     + ", set left=" + mFrame.left + " top=" + mFrame.top
@@ -5961,7 +6079,7 @@
             }
             return mSurface;
         }
-        
+
         void destroySurfaceLocked() {
             // Window is no longer on-screen, so can no longer receive
             // key events...  if we were waiting for it to finish
@@ -5974,7 +6092,7 @@
             if (mAppToken != null && this == mAppToken.startingWindow) {
                 mAppToken.startingDisplayed = false;
             }
-            
+
             if (localLOGV) Log.v(
                 TAG, "Window " + this
                 + " destroying surface " + mSurface + ", session " + mSession);
@@ -6064,7 +6182,7 @@
                 enableScreenIfNeededLocked();
 
                 applyEnterAnimationLocked(this);
-                
+
                 int i = mChildWindows.size();
                 while (i > 0) {
                     i--;
@@ -6074,7 +6192,7 @@
                         c.performShowLocked();
                     }
                 }
-                
+
                 if (mAttrs.type != TYPE_APPLICATION_STARTING
                         && mAppToken != null) {
                     mAppToken.firstWindowDrawn = true;
@@ -6090,13 +6208,13 @@
             }
             return true;
         }
-        
+
         // This must be called while inside a transaction.  Returns true if
         // there is more animation to run.
         boolean stepAnimationLocked(long currentTime, int dw, int dh) {
             if (!mDisplayFrozen) {
                 // We will run animations as long as the display isn't frozen.
-                
+
                 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
                     mHasTransformation = true;
                     mHasLocalTransformation = true;
@@ -6154,7 +6272,7 @@
                 mLocalAnimating = true;
                 mAnimation = null;
             }
-            
+
             if (!mAnimating && !mLocalAnimating) {
                 return false;
             }
@@ -6163,7 +6281,7 @@
                 TAG, "Animation done in " + this + ": exiting=" + mExiting
                 + ", reportedVisible="
                 + (mAppToken != null ? mAppToken.reportedVisible : false));
-            
+
             mAnimating = false;
             mLocalAnimating = false;
             mAnimation = null;
@@ -6187,7 +6305,7 @@
                 mFinishedStarting.add(mAppToken);
                 mH.sendEmptyMessage(H.FINISHED_STARTING);
             }
-            
+
             finishExit();
 
             if (mAppToken != null) {
@@ -6203,16 +6321,16 @@
                     + ": exiting=" + mExiting
                     + " remove=" + mRemoveOnExit
                     + " windowAnimating=" + isWindowAnimating());
-            
+
             final int N = mChildWindows.size();
             for (int i=0; i<N; i++) {
                 ((WindowState)mChildWindows.get(i)).finishExit();
             }
-            
+
             if (!mExiting) {
                 return;
             }
-            
+
             if (isWindowAnimating()) {
                 return;
             }
@@ -6239,7 +6357,7 @@
                 mRemoveOnExit = false;
             }
         }
-        
+
         boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
             if (dsdx < .99999f || dsdx > 1.00001f) return false;
             if (dtdy < .99999f || dtdy > 1.00001f) return false;
@@ -6247,7 +6365,7 @@
             if (dsdy < -.000001f || dsdy > .000001f) return false;
             return true;
         }
-        
+
         void computeShownFrameLocked() {
             final boolean selfTransformation = mHasLocalTransformation;
             Transformation attachedTransformation =
@@ -6258,7 +6376,7 @@
                     ? mAppToken.transformation : null;
             if (selfTransformation || attachedTransformation != null
                     || appTransformation != null) {
-                // cache often used attributes locally  
+                // cache often used attributes locally
                 final Rect frame = mFrame;
                 final float tmpFloats[] = mTmpFloats;
                 final Matrix tmpMatrix = mTmpMatrix;
@@ -6280,7 +6398,7 @@
                 // Here we must not transform the position of the surface
                 // since it is already included in the transformation.
                 //Log.i(TAG, "Transform: " + matrix);
-                
+
                 tmpMatrix.getValues(tmpFloats);
                 mDsDx = tmpFloats[Matrix.MSCALE_X];
                 mDtDx = tmpFloats[Matrix.MSKEW_X];
@@ -6315,14 +6433,14 @@
                 } else {
                     //Log.i(TAG, "Not applying alpha transform");
                 }
-                
+
                 if (localLOGV) Log.v(
                     TAG, "Continuing animation in " + this +
                     ": " + mShownFrame +
                     ", alpha=" + mTransformation.getAlpha());
                 return;
             }
-            
+
             mShownFrame.set(mFrame);
             mShownAlpha = mAlpha;
             mDsDx = 1;
@@ -6330,7 +6448,7 @@
             mDsDy = 0;
             mDtDy = 1;
         }
-        
+
         /**
          * Is this window visible?  It is not visible if there is no
          * surface, or we are in the process of running an exit animation
@@ -6393,7 +6511,7 @@
                         && (!mAttachedHidden || mAnimating);
             }
         }
-        
+
         /**
          * Like isOnScreen(), but we don't return true if the window is part
          * of a transition that has not yet been started.
@@ -6412,7 +6530,7 @@
             final AppWindowToken atoken = mAppToken;
             return mAnimation != null
                     || (attached != null && attached.mAnimation != null)
-                    || (atoken != null && 
+                    || (atoken != null &&
                             (atoken.animation != null
                                     || atoken.inPendingTransaction));
         }
@@ -6454,7 +6572,7 @@
             }
             return false;
         }
-        
+
         boolean isFullscreenOpaque(int screenWidth, int screenHeight) {
             if (mAttrs.format != PixelFormat.OPAQUE || mSurface == null
                     || mAnimation != null || mDrawPending || mCommitDrawPending) {
@@ -6546,7 +6664,7 @@
 
         void dump(PrintWriter pw, String prefix) {
             StringBuilder sb = new StringBuilder(64);
-            
+
             pw.print(prefix); pw.print("mSession="); pw.print(mSession);
                     pw.print(" mClient="); pw.println(mClient.asBinder());
             pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
@@ -6662,7 +6780,7 @@
                 + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
         }
     }
-    
+
     // -------------------------------------------------------------
     // Window Token State
     // -------------------------------------------------------------
@@ -6673,17 +6791,17 @@
 
         // The type of window this token is for, as per WindowManager.LayoutParams.
         final int windowType;
-        
+
         // Set if this token was explicitly added by a client, so should
         // not be removed when all windows are removed.
         final boolean explicit;
-        
+
         // For printing.
         String stringName;
-        
+
         // If this is an AppWindowToken, this is non-null.
         AppWindowToken appWindowToken;
-        
+
         // All of the windows associated with this token.
         final ArrayList<WindowState> windows = new ArrayList<WindowState>();
 
@@ -6734,7 +6852,7 @@
         int groupId = -1;
         boolean appFullscreen;
         int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-        
+
         // These are used for determining when all windows associated with
         // an activity have been drawn, so they can be made visible together
         // at the same time.
@@ -6743,20 +6861,20 @@
         int numDrawnWindows;
         boolean inPendingTransaction;
         boolean allDrawn;
-        
+
         // Is this token going to be hidden in a little while?  If so, it
         // won't be taken into account for setting the screen orientation.
         boolean willBeHidden;
-        
+
         // Is this window's surface needed?  This is almost like hidden, except
         // it will sometimes be true a little earlier: when the token has
         // been shown, but is still waiting for its app transition to execute
         // before making its windows shown.
         boolean hiddenRequested;
-        
+
         // Have we told the window clients to hide themselves?
         boolean clientHidden;
-        
+
         // Last visibility state we reported to the app token.
         boolean reportedVisible;
 
@@ -6765,16 +6883,16 @@
 
         // Have we been asked to have this token keep the screen frozen?
         boolean freezingScreen;
-        
+
         boolean animating;
         Animation animation;
         boolean hasTransformation;
         final Transformation transformation = new Transformation();
-        
+
         // Offset to the window of all layers in the token, for use by
         // AppWindowToken animations.
         int animLayerAdjustment;
-        
+
         // Information about an application starting window if displayed.
         StartingData startingData;
         WindowState startingWindow;
@@ -6789,7 +6907,7 @@
             appWindowToken = this;
             appToken = _token;
         }
-        
+
         public void setAnimation(Animation anim) {
             if (localLOGV) Log.v(
                 TAG, "Setting animation in " + this + ": " + anim);
@@ -6804,13 +6922,13 @@
             } else if (zorder == Animation.ZORDER_BOTTOM) {
                 adj = -TYPE_LAYER_OFFSET;
             }
-            
+
             if (animLayerAdjustment != adj) {
                 animLayerAdjustment = adj;
                 updateLayers();
             }
         }
-        
+
         public void setDummyAnimation() {
             if (animation == null) {
                 if (localLOGV) Log.v(
@@ -6825,7 +6943,7 @@
                 animating = true;
             }
         }
-        
+
         void updateLayers() {
             final int N = allAppWindows.size();
             final int adj = animLayerAdjustment;
@@ -6839,7 +6957,7 @@
                 }
             }
         }
-        
+
         void sendAppVisibilityToClients() {
             final int N = allAppWindows.size();
             for (int i=0; i<N; i++) {
@@ -6856,7 +6974,7 @@
                 }
             }
         }
-        
+
         void showAllWindowsLocked() {
             final int NW = allAppWindows.size();
             for (int i=0; i<NW; i++) {
@@ -6866,12 +6984,12 @@
                 w.performShowLocked();
             }
         }
-        
+
         // This must be called while inside a transaction.
         boolean stepAnimationLocked(long currentTime, int dw, int dh) {
             if (!mDisplayFrozen) {
                 // We will run animations as long as the display isn't frozen.
-                
+
                 if (animation == sDummyAnimation) {
                     // This guy is going to animate, but not yet.  For now count
                     // it is not animating for purposes of scheduling transactions;
@@ -6879,7 +6997,7 @@
                     // a real animation and the next call will execute normally.
                     return false;
                 }
-                
+
                 if ((allDrawn || animating || startingDisplayed) && animation != null) {
                     if (!animating) {
                         if (DEBUG_ANIM) Log.v(
@@ -6915,7 +7033,7 @@
             }
 
             hasTransformation = false;
-            
+
             if (!animating) {
                 return false;
             }
@@ -6925,7 +7043,7 @@
             if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
                 moveInputMethodWindowsIfNeededLocked(true);
             }
-            
+
             if (DEBUG_ANIM) Log.v(
                     TAG, "Animation done in " + this
                     + ": reportedVisible=" + reportedVisible);
@@ -6935,13 +7053,13 @@
                 animLayerAdjustment = 0;
                 updateLayers();
             }
-            
+
             final int N = windows.size();
             for (int i=0; i<N; i++) {
                 ((WindowState)windows.get(i)).finishExit();
             }
             updateReportedVisibilityLocked();
-            
+
             return false;
         }
 
@@ -6949,11 +7067,11 @@
             if (appToken == null) {
                 return;
             }
-            
+
             int numInteresting = 0;
             int numVisible = 0;
             boolean nowGone = true;
-            
+
             if (DEBUG_VISIBILITY) Log.v(TAG, "Update reported visibility: " + this);
             final int N = allAppWindows.size();
             for (int i=0; i<N; i++) {
@@ -6987,7 +7105,7 @@
                     nowGone = false;
                 }
             }
-            
+
             boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
             if (DEBUG_VISIBILITY) Log.v(TAG, "VIS " + this + ": interesting="
                     + numInteresting + " visible=" + numVisible);
@@ -7004,7 +7122,7 @@
                     mH.sendMessage(m);
             }
         }
-        
+
         void dump(PrintWriter pw, String prefix) {
             super.dump(pw, prefix);
             if (appToken != null) {
@@ -7069,7 +7187,7 @@
             return stringName;
         }
     }
-    
+
     public static WindowManager.LayoutParams findAnimations(
             ArrayList<AppWindowToken> order,
             ArrayList<AppWindowToken> tokenList1,
@@ -7077,7 +7195,7 @@
         // 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);
@@ -7106,10 +7224,10 @@
                 }
             }
         }
-        
+
         return animParams;
     }
-    
+
     // -------------------------------------------------------------
     // DummyAnimation
     // -------------------------------------------------------------
@@ -7123,7 +7241,7 @@
         }
     }
     static final Animation sDummyAnimation = new DummyAnimation();
-    
+
     // -------------------------------------------------------------
     // Async Handler
     // -------------------------------------------------------------
@@ -7134,7 +7252,7 @@
         final CharSequence nonLocalizedLabel;
         final int labelRes;
         final int icon;
-        
+
         StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
                 int _labelRes, int _icon) {
             pkg = _pkg;
@@ -7161,19 +7279,19 @@
         public static final int ENABLE_SCREEN = 16;
         public static final int APP_FREEZE_TIMEOUT = 17;
         public static final int COMPUTE_AND_SEND_NEW_CONFIGURATION = 18;
-        
+
         private Session mLastReportedHold;
-        
+
         public H() {
         }
-        
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case REPORT_FOCUS_CHANGE: {
                     WindowState lastFocus;
                     WindowState newFocus;
-    
+
                     synchronized(mWindowMap) {
                         lastFocus = mLastFocus;
                         newFocus = mCurrentFocus;
@@ -7217,7 +7335,7 @@
 
                 case REPORT_LOSING_FOCUS: {
                     ArrayList<WindowState> losers;
-    
+
                     synchronized(mWindowMap) {
                         losers = mLosingFocus;
                         mLosingFocus = new ArrayList<WindowState>();
@@ -7249,10 +7367,10 @@
                         // Animation has been canceled... do nothing.
                         return;
                     }
-                    
+
                     if (DEBUG_STARTING_WINDOW) Log.v(TAG, "Add starting "
                             + wtoken + ": pkg=" + sd.pkg);
-                    
+
                     View view = null;
                     try {
                         view = mPolicy.addStartingWindow(
@@ -7379,7 +7497,7 @@
                     } catch (RemoteException ex) {
                     }
                 } break;
-                
+
                 case WINDOW_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
                         Log.w(TAG, "Window freeze timeout expired.");
@@ -7396,7 +7514,7 @@
                     }
                     break;
                 }
-                
+
                 case HOLD_SCREEN_CHANGED: {
                     Session oldHold;
                     Session newHold;
@@ -7405,7 +7523,7 @@
                         newHold = (Session)msg.obj;
                         mLastReportedHold = newHold;
                     }
-                    
+
                     if (oldHold != newHold) {
                         try {
                             if (oldHold != null) {
@@ -7423,7 +7541,7 @@
                     }
                     break;
                 }
-                
+
                 case APP_TRANSITION_TIMEOUT: {
                     synchronized (mWindowMap) {
                         if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
@@ -7436,7 +7554,7 @@
                     }
                     break;
                 }
-                
+
                 case PERSIST_ANIMATION_SCALE: {
                     Settings.System.putFloat(mContext.getContentResolver(),
                             Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
@@ -7444,7 +7562,7 @@
                             Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
                     break;
                 }
-                
+
                 case FORCE_GC: {
                     synchronized(mWindowMap) {
                         if (mAnimationPending) {
@@ -7464,12 +7582,12 @@
                     Runtime.getRuntime().gc();
                     break;
                 }
-                
+
                 case ENABLE_SCREEN: {
                     performEnableScreen();
                     break;
                 }
-                
+
                 case APP_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
                         Log.w(TAG, "App freeze timeout expired.");
@@ -7485,14 +7603,14 @@
                     }
                     break;
                 }
-                
+
                 case COMPUTE_AND_SEND_NEW_CONFIGURATION: {
-                    if (updateOrientationFromAppTokens(null, null) != null) {
+                    if (updateOrientationFromAppTokensUnchecked(null, null) != null) {
                         sendNewConfiguration();
                     }
                     break;
                 }
-                
+
             }
         }
     }
@@ -7526,7 +7644,7 @@
         }
         return false;
     }
-    
+
     // -------------------------------------------------------------
     // Internals
     // -------------------------------------------------------------
@@ -7534,7 +7652,7 @@
     final WindowState windowForClientLocked(Session session, IWindow client) {
         return windowForClientLocked(session, client.asBinder());
     }
-    
+
     final WindowState windowForClientLocked(Session session, IBinder client) {
         WindowState win = mWindowMap.get(client);
         if (localLOGV) Log.v(
@@ -7559,7 +7677,7 @@
         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) {
@@ -7615,11 +7733,11 @@
                 }
             }
         }
-        
+
         mInLayout = true;
         try {
             performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
-            
+
             int i = mPendingRemove.size()-1;
             if (i >= 0) {
                 while (i >= 0) {
@@ -7655,7 +7773,7 @@
         int i;
 
         // FIRST LOOP: Perform a layout, if needed.
-        
+
         while (mLayoutNeeded) {
             mPolicy.beginLayoutLw(dw, dh);
 
@@ -7690,7 +7808,7 @@
                     }
                 }
             }
-            
+
             // 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
@@ -7721,7 +7839,7 @@
             }
         }
     }
-    
+
     private final void performLayoutAndPlaceSurfacesLockedInner(
             boolean recoveringMemory) {
         final long currentTime = SystemClock.uptimeMillis();
@@ -7732,13 +7850,12 @@
         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.
@@ -7752,7 +7869,6 @@
         }
 
         // SECOND LOOP: Execute animations and update visibility of windows.
-        
         boolean orientationChangeComplete = true;
         Session holdScreen = null;
         float screenBrightness = -1;
@@ -8063,7 +8179,7 @@
                             !w.mLastContentInsets.equals(w.mContentInsets);
                         w.mVisibleInsetsChanged =
                             !w.mLastVisibleInsets.equals(w.mVisibleInsets);
-                        if (!w.mLastFrame.equals(w.mFrame) 
+                        if (!w.mLastFrame.equals(w.mFrame)
                                 || w.mContentInsetsChanged
                                 || w.mVisibleInsetsChanged) {
                             w.mLastFrame.set(w.mFrame);
@@ -8085,7 +8201,7 @@
                                     w.mAppToken.allDrawn = false;
                                 }
                             }
-                            if (DEBUG_ORIENTATION) Log.v(TAG, 
+                            if (DEBUG_ORIENTATION) Log.v(TAG,
                                     "Resizing window " + w + " to " + w.mFrame);
                             mResizingWindows.add(w);
                         } else if (w.mOrientationChanging) {
@@ -8275,7 +8391,7 @@
                                     if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
                                             + mDimSurface + ": CREATE");
                                     try {
-                                        mDimSurface = new Surface(mFxSession, 0, 
+                                        mDimSurface = new Surface(mFxSession, 0,
                                                 -1, 16, 16,
                                                 PixelFormat.OPAQUE,
                                                 Surface.FX_SURFACE_DIM);
@@ -8330,7 +8446,7 @@
                                     if (SHOW_TRANSACTIONS) Log.i(TAG, "  BLUR "
                                             + mBlurSurface + ": CREATE");
                                     try {
-                                        mBlurSurface = new Surface(mFxSession, 0, 
+                                        mBlurSurface = new Surface(mFxSession, 0,
                                                 -1, 16, 16,
                                                 PixelFormat.OPAQUE,
                                                 Surface.FX_SURFACE_BLUR);
@@ -8384,7 +8500,7 @@
                 } else {
                     more = false;
                 }
-                
+
                 // Do we need to continue animating?
                 if (more) {
                     if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM "
@@ -8410,7 +8526,7 @@
                     }
                 }
             }
-            
+
             if (!blurring && mBlurShown) {
                 if (SHOW_TRANSACTIONS) Log.i(TAG, "  BLUR " + mBlurSurface
                         + ": HIDE");
@@ -8428,7 +8544,7 @@
         }
 
         Surface.closeTransaction();
-        
+
         if (DEBUG_ORIENTATION && mDisplayFrozen) Log.v(TAG,
                 "With display frozen, orientationChangeComplete="
                 + orientationChangeComplete);
@@ -8441,7 +8557,7 @@
                 stopFreezingDisplayLocked();
             }
         }
-        
+
         i = mResizingWindows.size();
         if (i > 0) {
             do {
@@ -8459,7 +8575,7 @@
             } while (i > 0);
             mResizingWindows.clear();
         }
-        
+
         // Destroy the surface of any windows that are no longer visible.
         i = mDestroySurface.size();
         if (i > 0) {
@@ -8518,13 +8634,13 @@
             mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
         }
     }
-    
+
     /**
      * 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.
      */
     boolean showSurfaceRobustlyLocked(WindowState win) {
@@ -8536,22 +8652,22 @@
         } catch (RuntimeException e) {
             Log.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
         }
-        
+
         reclaimSomeSurfaceMemoryLocked(win, "show");
-        
+
         return false;
     }
-    
+
     void reclaimSomeSurfaceMemoryLocked(WindowState win, 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
@@ -8585,7 +8701,7 @@
                     }
                 }
             }
-            
+
             boolean killedApps = false;
             if (!leakedSurface) {
                 Log.w(TAG, "No leaked surfaces; killing applicatons!");
@@ -8609,7 +8725,7 @@
                     }
                 }
             }
-            
+
             if (leakedSurface || killedApps) {
                 // We managed to reclaim some memory, so get rid of the trouble
                 // surface and ask the app to request another one.
@@ -8618,7 +8734,7 @@
                     surface.clear();
                     win.mSurface = null;
                 }
-                
+
                 try {
                     win.mClient.dispatchGetNewSurface();
                 } catch (RemoteException e) {
@@ -8628,7 +8744,7 @@
             Binder.restoreCallingIdentity(callingIdentity);
         }
     }
-    
+
     private boolean updateFocusedWindowLocked(int mode) {
         WindowState newFocus = computeFocusedWindowLocked();
         if (mCurrentFocus != newFocus) {
@@ -8641,7 +8757,7 @@
             final WindowState oldFocus = mCurrentFocus;
             mCurrentFocus = newFocus;
             mLosingFocus.remove(newFocus);
-            
+
             final WindowState imWindow = mInputMethodWindow;
             if (newFocus != imWindow && oldFocus != imWindow) {
                 if (moveInputMethodWindowsIfNeededLocked(
@@ -8657,7 +8773,7 @@
                     assignLayersLocked();
                 }
             }
-            
+
             if (newFocus != null && mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
                 mKeyWaiter.handleNewWindowLocked(newFocus);
             }
@@ -8685,13 +8801,13 @@
                 + ", 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.
@@ -8748,9 +8864,9 @@
             }
             return;
         }
-        
+
         mScreenFrozenLock.acquire();
-        
+
         long now = SystemClock.uptimeMillis();
         //Log.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
         if (mFreezeGcPending != 0) {
@@ -8763,32 +8879,32 @@
         } 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);
     }
-    
+
     private void stopFreezingDisplayLocked() {
         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) {
@@ -8804,10 +8920,10 @@
         mH.removeMessages(H.FORCE_GC);
         mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
                 2000);
-        
+
         mScreenFrozenLock.release();
     }
-    
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -8817,7 +8933,7 @@
                     + ", uid=" + Binder.getCallingUid());
             return;
         }
-        
+
         synchronized(mWindowMap) {
             pw.println("Current Window Manager state:");
             for (int i=mWindows.size()-1; i>=0; i--) {