auto import from //branches/cupcake/...@126645
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 63d7c94..139aaa3 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -211,6 +211,11 @@
     boolean mShowRequested;
     
     /**
+     * Set if we were explicitly told to show the input method.
+     */
+    boolean mShowExplicitlyRequested;
+    
+    /**
      * Set if we last told the input method to show itself.
      */
     boolean mInputShown;
@@ -569,7 +574,9 @@
                     MSG_RESTART_INPUT, session, mCurAttribute));
         }
         if (mShowRequested) {
-            showCurrentInputLocked();
+            if (DEBUG) Log.v(TAG, "Attach new input asks to show input");
+            showCurrentInputLocked(mShowExplicitlyRequested
+                    ? 0 : InputMethodManager.SHOW_IMPLICIT);
         }
         return needResult
                 ? new InputBindResult(session.session, mCurId, mCurSeq)
@@ -820,7 +827,7 @@
         }
     }
     
-    public void showSoftInput(IInputMethodClient client) {
+    public void showSoftInput(IInputMethodClient client, int flags) {
         synchronized (mMethodMap) {
             if (mCurClient == null || client == null
                     || mCurClient.client.asBinder() != client.asBinder()) {
@@ -836,22 +843,25 @@
                 }
             }
 
-            showCurrentInputLocked();
+            if (DEBUG) Log.v(TAG, "Client requesting input be shown");
+            showCurrentInputLocked(flags);
         }
     }
     
-    void showCurrentInputLocked() {
+    void showCurrentInputLocked(int flags) {
         mShowRequested = true;
-        if (!mInputShown) {
-            if (mCurMethod != null) {
-                executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
-                        MSG_SHOW_SOFT_INPUT, mCurMethod));
-                mInputShown = true;
-            }
+        if ((flags&InputMethodManager.SHOW_IMPLICIT) == 0) {
+            mShowExplicitlyRequested = true;
+        }
+        if (mCurMethod != null) {
+            executeOrSendMessage(mCurMethod, mCaller.obtainMessageIO(
+                    MSG_SHOW_SOFT_INPUT, mShowExplicitlyRequested ? 1 : 0,
+                            mCurMethod));
+            mInputShown = true;
         }
     }
     
-    public void hideSoftInput(IInputMethodClient client) {
+    public void hideSoftInput(IInputMethodClient client, int flags) {
         synchronized (mMethodMap) {
             if (mCurClient == null || client == null
                     || mCurClient.client.asBinder() != client.asBinder()) {
@@ -867,25 +877,34 @@
                 }
             }
 
-            hideCurrentInputLocked();
+            if (DEBUG) Log.v(TAG, "Client requesting input be hidden");
+            hideCurrentInputLocked(flags);
         }
     }
     
-    void hideCurrentInputLocked() {
+    void hideCurrentInputLocked(int flags) {
+        if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
+                && mShowExplicitlyRequested) {
+            if (DEBUG) Log.v(TAG,
+                    "Not hiding: explicit show not cancelled by non-explicit hide");
+            return;
+        }
         if (mInputShown && mCurMethod != null) {
             executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
                     MSG_HIDE_SOFT_INPUT, mCurMethod));
         }
         mInputShown = false;
         mShowRequested = false;
+        mShowExplicitlyRequested = false;
     }
     
     public void windowGainedFocus(IInputMethodClient client,
-            boolean viewHasFocus, int softInputMode, boolean first,
-            int windowFlags) {
+            boolean viewHasFocus, boolean isTextEditor, int softInputMode,
+            boolean first, int windowFlags) {
         synchronized (mMethodMap) {
             if (DEBUG) Log.v(TAG, "windowGainedFocus: " + client.asBinder()
                     + " viewHasFocus=" + viewHasFocus
+                    + " isTextEditor=" + isTextEditor
                     + " softInputMode=#" + Integer.toHexString(softInputMode)
                     + " first=" + first + " flags=#"
                     + Integer.toHexString(windowFlags));
@@ -906,35 +925,45 @@
 
             switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
                 case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
-                    if (!viewHasFocus || (softInputMode &
+                    if (!isTextEditor || (softInputMode &
                             WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
                             != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
-                        if ((windowFlags&WindowManager.LayoutParams
-                                .FLAG_ALT_FOCUSABLE_IM) == 0) {
+                        if (WindowManager.LayoutParams.mayUseInputMethod(windowFlags)) {
                             // There is no focus view, and this window will
-                            // be behind any soft input window, then hide the
+                            // be behind any soft input window, so hide the
                             // soft input window if it is shown.
-                            hideCurrentInputLocked();
+                            if (DEBUG) Log.v(TAG, "Unspecified window will hide input");
+                            hideCurrentInputLocked(0);
                         }
+                    } else if (isTextEditor && (softInputMode &
+                            WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
+                            == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
+                            && (softInputMode &
+                                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
+                        // There is a focus view, and we are navigating forward
+                        // into the window, so show the input window for the user.
+                        if (DEBUG) Log.v(TAG, "Unspecified window will show input");
+                        showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT);
                     }
                     break;
                 case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
                     // Do nothing.
                     break;
                 case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
-                    hideCurrentInputLocked();
-                    break;
-                case WindowManager.LayoutParams.SOFT_INPUT_STATE_FIRST_VISIBLE:
-                    if (first && !viewHasFocus && (windowFlags
-                            & WindowManager.LayoutParams.FLAG_RESTORED_STATE) == 0) {
-                        showCurrentInputLocked();
-                    }
+                    if (DEBUG) Log.v(TAG, "Window asks to hide input");
+                    hideCurrentInputLocked(0);
                     break;
                 case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
-                    if (viewHasFocus) {
-                        showCurrentInputLocked();
+                    if ((softInputMode &
+                            WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
+                        if (DEBUG) Log.v(TAG, "Window asks to show input going forward");
+                        showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT);
                     }
                     break;
+                case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
+                    if (DEBUG) Log.v(TAG, "Window asks to always show input");
+                    showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT);
+                    break;
             }
         }
     }
@@ -968,18 +997,13 @@
         }
     }
 
-    public void hideMySoftInput(IBinder token) {
+    public void hideMySoftInput(IBinder token, int flags) {
         synchronized (mMethodMap) {
             if (mCurToken == null || mCurToken != token) {
                 Log.w(TAG, "Ignoring hideInputMethod of token: " + token);
             }
 
-            if (mInputShown && mCurMethod != null) {
-                executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
-                        MSG_HIDE_SOFT_INPUT, mCurMethod));
-            }
-            mInputShown = false;
-            mShowRequested = false;
+            hideCurrentInputLocked(flags);
         }
     }
 
@@ -1028,7 +1052,7 @@
                 return true;
             case MSG_SHOW_SOFT_INPUT:
                 try {
-                    ((IInputMethod)msg.obj).showSoftInput();
+                    ((IInputMethod)msg.obj).showSoftInput(msg.arg1 != 0);
                 } catch (RemoteException e) {
                 }
                 return true;
@@ -1400,6 +1424,7 @@
             p.println("  mCurMethod=" + mCurMethod);
             p.println("  mEnabledSession=" + mEnabledSession);
             p.println("  mShowRequested=" + mShowRequested
+                    + " mShowExplicitlyRequested=" + mShowExplicitlyRequested
                     + " mInputShown=" + mInputShown);
             p.println("  mScreenOn=" + mScreenOn);
         }
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index 77182f7..9874042 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -127,10 +127,10 @@
     
     public void getInputConfiguration(Configuration config) {
         synchronized (mFirst) {
-            config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
-                    //Resources.Configuration.TOUCHSCREEN_NOTOUCH;
-            config.keyboard = Configuration.KEYBOARD_QWERTY;
-            config.navigation = Configuration.NAVIGATION_TRACKBALL;
+            config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
+            config.keyboard = Configuration.KEYBOARD_NOKEYS;
+            config.navigation = Configuration.NAVIGATION_NONAV;
+            
             final int N = mDevices.size();
             for (int i=0; i<N; i++) {
                 InputDevice d = mDevices.valueAt(i);
@@ -140,6 +140,11 @@
                                 = Configuration.TOUCHSCREEN_FINGER;
                         //Log.i("foo", "***** HAVE TOUCHSCREEN!");
                     }
+                    if ((d.classes&RawInputEvent.CLASS_ALPHAKEY) != 0) {
+                        config.keyboard
+                                = Configuration.KEYBOARD_QWERTY;
+                        //Log.i("foo", "***** HAVE QWERTY!");
+                    }
                     if ((d.classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
                         config.navigation
                                 = Configuration.NAVIGATION_TRACKBALL;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index f2483ff..2d61b1e 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1460,7 +1460,7 @@
                  * current power conditions (i.e, not plugged in, plugged in to USB,
                  * or plugged in to AC).
                  */
-                if (!shouldStayAwake(stayAwakeConditions, mPluggedType)) {
+                if (!shouldWifiStayAwake(stayAwakeConditions, mPluggedType)) {
                     long triggerTime = System.currentTimeMillis() + idleMillis;
                     mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
                 }
@@ -1477,8 +1477,8 @@
                  * the already-set timer.
                  */
                 int pluggedType = intent.getIntExtra("plugged", 0);
-                if (mScreenOff && shouldStayAwake(stayAwakeConditions, mPluggedType) &&
-                        !shouldStayAwake(stayAwakeConditions, pluggedType)) {
+                if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) &&
+                        !shouldWifiStayAwake(stayAwakeConditions, pluggedType)) {
                     long triggerTime = System.currentTimeMillis() + idleMillis;
                     mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
                     mPluggedType = pluggedType;
@@ -1493,6 +1493,30 @@
         }
 
         /**
+         * Determines whether the Wi-Fi chipset should stay awake or be put to
+         * sleep. Looks at the setting for the sleep policy and the current
+         * conditions.
+         * 
+         * @see #shouldDeviceStayAwake(int, int)
+         */
+        private boolean shouldWifiStayAwake(int stayAwakeConditions, int pluggedType) {
+            int wifiSleepPolicy = Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
+
+            if (wifiSleepPolicy == Settings.System.WIFI_SLEEP_POLICY_NEVER) {
+                // Never sleep
+                return true;
+            } else if ((wifiSleepPolicy == Settings.System.WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED) &&
+                    (pluggedType != 0)) {
+                // Never sleep while plugged, and we're plugged
+                return true;
+            } else {
+                // Default
+                return shouldDeviceStayAwake(stayAwakeConditions, pluggedType);
+            }
+        }
+        
+        /**
          * Determine whether the bit value corresponding to {@code pluggedType} is set in
          * the bit string {@code stayAwakeConditions}. Because a {@code pluggedType} value
          * of {@code 0} isn't really a plugged type, but rather an indication that the
@@ -1506,7 +1530,7 @@
          * @return {@code true} if {@code pluggedType} indicates that the device is
          * supposed to stay awake, {@code false} otherwise.
          */
-        private boolean shouldStayAwake(int stayAwakeConditions, int pluggedType) {
+        private boolean shouldDeviceStayAwake(int stayAwakeConditions, int pluggedType) {
             return (stayAwakeConditions & pluggedType) != 0;
         }
     };
@@ -1528,7 +1552,6 @@
         boolean airplaneMode = isAirplaneModeOn();
         boolean lockHeld = mLocks.hasLocks();
         int strongestLockMode;
-
         boolean wifiShouldBeEnabled = wifiEnabled && !airplaneMode;
         boolean wifiShouldBeStarted = !mDeviceIdle || lockHeld;
         if (mDeviceIdle && lockHeld) {
@@ -1562,11 +1585,7 @@
     }
 
     private void registerForBroadcasts() {
-        String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_RADIOS);
-        boolean isAirplaneSensitive = airplaneModeRadios == null
-            || airplaneModeRadios.contains(Settings.System.RADIO_WIFI);
-        if (isAirplaneSensitive) {
+        if (isAirplaneSensitive()) {
             mContext.registerReceiver(mReceiver,
                 new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
         }
@@ -1579,12 +1598,21 @@
         mContext.registerReceiver(mReceiver,
                 new IntentFilter(ACTION_DEVICE_IDLE));
     }
+    
+    private boolean isAirplaneSensitive() {
+        String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
+                Settings.System.AIRPLANE_MODE_RADIOS);
+        return airplaneModeRadios == null
+            || airplaneModeRadios.contains(Settings.System.RADIO_WIFI);
+    }
+
     /**
-     * Returns true if airplane mode is currently on.
+     * Returns true if Wi-Fi is sensitive to airplane mode, and airplane mode is
+     * currently on.
      * @return {@code true} if airplane mode is on.
      */
     private boolean isAirplaneModeOn() {
-        return Settings.System.getInt(mContext.getContentResolver(),
+        return isAirplaneSensitive() && Settings.System.getInt(mContext.getContentResolver(),
                 Settings.System.AIRPLANE_MODE_ON, 0) == 1;
     }
 
diff --git a/services/java/com/android/server/WifiWatchdogService.java b/services/java/com/android/server/WifiWatchdogService.java
index e686bf0..9578c2e 100644
--- a/services/java/com/android/server/WifiWatchdogService.java
+++ b/services/java/com/android/server/WifiWatchdogService.java
@@ -231,7 +231,7 @@
      */
     private int getBackgroundCheckDelayMs() {
         return Settings.Secure.getInt(mContentResolver,
-            Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS, 5000);
+            Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS, 60000);
     }
     
     /**
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 9671743..881add1 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -541,7 +541,7 @@
         return -1;
     }
     
-    private void addWindowToListInOrderLocked(WindowState win) {
+    private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
         final IWindow client = win.mClient;
         final WindowToken token = win.mToken;
         final ArrayList localmWindows = mWindows;
@@ -669,7 +669,9 @@
                     + i + " of " + N);
                 localmWindows.add(i, win);
             }
-            token.windows.add(tokenWindowsPos, win);
+            if (addToToken) {
+                token.windows.add(tokenWindowsPos, win);
+            }
 
         } else {
             // Figure out this window's ordering relative to the window
@@ -689,7 +691,9 @@
                     // For negative sublayers, we go below all windows
                     // in the same sublayer.
                     if (wSublayer >= sublayer) {
-                        token.windows.add(i, win);
+                        if (addToToken) {
+                            token.windows.add(i, win);
+                        }
                         placeWindowBefore(
                             wSublayer >= 0 ? attached : w, win);
                         break;
@@ -698,14 +702,18 @@
                     // For positive sublayers, we go above all windows
                     // in the same sublayer.
                     if (wSublayer > sublayer) {
-                        token.windows.add(i, win);
+                        if (addToToken) {
+                            token.windows.add(i, win);
+                        }
                         placeWindowBefore(w, win);
                         break;
                     }
                 }
             }
             if (i >= NA) {
-                token.windows.add(win);
+                if (addToToken) {
+                    token.windows.add(win);
+                }
                 if (sublayer < 0) {
                     placeWindowBefore(attached, win);
                 } else {
@@ -717,7 +725,7 @@
             }
         }
         
-        if (win.mAppToken != null) {
+        if (win.mAppToken != null && addToToken) {
             win.mAppToken.allAppWindows.add(win);
         }
     }
@@ -759,19 +767,46 @@
             return;
         }
         win.mTargetAppToken = null;
-        addWindowToListInOrderLocked(win);
+        addWindowToListInOrderLocked(win, true);
         moveInputMethodDialogsLocked(pos);
     }
     
+    private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
+        int wpos = mWindows.indexOf(win);
+        if (wpos >= 0) {
+            if (wpos < interestingPos) interestingPos--;
+            mWindows.remove(wpos);
+            int NC = win.mChildWindows.size();
+            while (NC > 0) {
+                NC--;
+                WindowState cw = (WindowState)win.mChildWindows.get(NC);
+                int cpos = mWindows.indexOf(cw);
+                if (cpos >= 0) {
+                    if (cpos < interestingPos) interestingPos--;
+                    mWindows.remove(cpos);
+                }
+            }
+        }
+        return interestingPos;
+    }
+    
+    private void reAddWindowToListInOrderLocked(WindowState win) {
+        addWindowToListInOrderLocked(win, false);
+        // This is a hack to get all of the child windows added as well
+        // at the right position.  Child windows should be rare and
+        // this case should be rare, so it shouldn't be that big a deal.
+        int wpos = mWindows.indexOf(win);
+        if (wpos >= 0) {
+            mWindows.remove(wpos);
+            reAddWindowLocked(wpos, win);
+        }
+    }
+    
     void moveInputMethodDialogsLocked(int pos) {
         ArrayList<WindowState> dialogs = mInputMethodDialogs;
         final int N = dialogs.size();
         for (int i=0; i<N; i++) {
-            int wpos = mWindows.indexOf(dialogs.get(i));
-            if (wpos >= 0) {
-                if (wpos < pos) pos--;
-                mWindows.remove(wpos);
-            }
+            pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
         }
         if (pos >= 0) {
             final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
@@ -782,15 +817,14 @@
             for (int i=0; i<N; i++) {
                 WindowState win = dialogs.get(i);
                 win.mTargetAppToken = targetAppToken;
-                mWindows.add(pos, win);
-                pos++;
+                pos = reAddWindowLocked(pos, win);
             }
             return;
         }
         for (int i=0; i<N; i++) {
             WindowState win = dialogs.get(i);
             win.mTargetAppToken = null;
-            addWindowToListInOrderLocked(win);
+            reAddWindowToListInOrderLocked(win);
         }
     }
     
@@ -806,26 +840,49 @@
             // In this case, the input method windows are to be placed
             // immediately above the window they are targeting.
             
-            WindowState firstImWin = imPos < DN
+            // 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;
-            if (imWin != null) {
-                if (imWin == firstImWin) {
-                    // Already at the correct location!
-                    return false;
+                    
+            // Figure out the actual input method window that should be
+            // at the bottom of their stack.
+            WindowState baseImWin = imWin != null
+                    ? imWin : mInputMethodDialogs.get(0);
+            if (baseImWin.mChildWindows.size() > 0) {
+                WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
+                if (cw.mSubLayer < 0) baseImWin = cw;
+            }
+            
+            if (firstImWin == baseImWin) {
+                // The windows haven't moved...  but are they still contiguous?
+                // First find the top IM window.
+                int pos = imPos+1;
+                while (pos < N) {
+                    if (!((WindowState)mWindows.get(pos)).mIsImWindow) {
+                        break;
+                    }
+                    pos++;
                 }
-            } else {
-                if (mInputMethodDialogs.get(0) == firstImWin) {
-                    // Already at the correct location!
+                pos++;
+                // Now there should be no more input method windows above.
+                while (pos < N) {
+                    if (((WindowState)mWindows.get(pos)).mIsImWindow) {
+                        break;
+                    }
+                    pos++;
+                }
+                if (pos >= N) {
+                    // All is good!
                     return false;
                 }
             }
             
             if (imWin != null) {
-                int oldPos = mWindows.indexOf(imWin);
-                mWindows.remove(oldPos);
-                if (imPos > oldPos) imPos--;
+                imPos = tmpRemoveWindowLocked(imPos, imWin);
                 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
-                mWindows.add(imPos, imWin);
+                reAddWindowLocked(imPos, imWin);
                 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
             } else {
                 moveInputMethodDialogsLocked(imPos);
@@ -836,9 +893,9 @@
             // because they aren't currently associated with a focus window.
             
             if (imWin != null) {
-                mWindows.remove(imWin);
+                tmpRemoveWindowLocked(0, imWin);
                 imWin.mTargetAppToken = null;
-                addWindowToListInOrderLocked(imWin);
+                reAddWindowToListInOrderLocked(imWin);
                 if (DN > 0) moveInputMethodDialogsLocked(-1);;
             } else {
                 moveInputMethodDialogsLocked(-1);;
@@ -985,10 +1042,11 @@
                 imMayMove = false;
             } else if (attrs.type == TYPE_INPUT_METHOD_DIALOG) {
                 mInputMethodDialogs.add(win);
+                addWindowToListInOrderLocked(win, true);
                 adjustInputMethodDialogsLocked();
                 imMayMove = false;
             } else {
-                addWindowToListInOrderLocked(win);
+                addWindowToListInOrderLocked(win, true);
             }
             
             Binder.restoreCallingIdentity(origId);
@@ -1910,6 +1968,10 @@
         }
     }
 
+    public int getPendingAppTransition() {
+        return mNextAppTransition;
+    }
+    
     public void executeAppTransition() {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "executeAppTransition()")) {
@@ -1988,7 +2050,7 @@
                         mWindows.remove(startingWindow);
                         ttoken.windows.remove(startingWindow);
                         ttoken.allAppWindows.remove(startingWindow);
-                        addWindowToListInOrderLocked(startingWindow);
+                        addWindowToListInOrderLocked(startingWindow, true);
                         wtoken.allAppWindows.add(startingWindow);
                         
                         // Propagate other interesting state between the
@@ -2487,26 +2549,30 @@
         return 0;
     }
 
+    private final int reAddWindowLocked(int index, WindowState win) {
+        final int NCW = win.mChildWindows.size();
+        boolean added = false;
+        for (int j=0; j<NCW; j++) {
+            WindowState cwin = (WindowState)win.mChildWindows.get(j);
+            if (cwin.mSubLayer >= 0) {
+                mWindows.add(index, win);
+                index++;
+                added = true;
+            }
+            mWindows.add(index, cwin);
+            index++;
+        }
+        if (!added) {
+            mWindows.add(index, win);
+            index++;
+        }
+        return index;
+    }
+    
     private final int reAddAppWindowsLocked(int index, WindowToken token) {
         final int NW = token.windows.size();
         for (int i=0; i<NW; i++) {
-            WindowState win = token.windows.get(i);
-            final int NCW = win.mChildWindows.size();
-            boolean added = false;
-            for (int j=0; j<NCW; j++) {
-                WindowState cwin = (WindowState)win.mChildWindows.get(j);
-                if (cwin.mSubLayer >= 0) {
-                    mWindows.add(index, win);
-                    index++;
-                    added = true;
-                }
-                mWindows.add(index, cwin);
-                index++;
-            }
-            if (!added) {
-                mWindows.add(index, win);
-                index++;
-            }
+            index = reAddWindowLocked(index, token.windows.get(i));
         }
         return index;
     }
@@ -4921,6 +4987,7 @@
         final int mBaseLayer;
         final int mSubLayer;
         final boolean mLayoutAttached;
+        final boolean mIsImWindow;
         int mViewVisibility;
         boolean mPolicyVisibility = true;
         boolean mAppFreezing;
@@ -5071,6 +5138,7 @@
                 mDeathRecipient = null;
                 mAttachedWindow = null;
                 mLayoutAttached = false;
+                mIsImWindow = false;
                 mBaseLayer = 0;
                 mSubLayer = 0;
                 return;
@@ -5089,6 +5157,8 @@
                 mAttachedWindow.mChildWindows.add(this);
                 mLayoutAttached = mAttrs.type !=
                         WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+                mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
+                        || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
             } else {
                 // The multiplier here is to reserve space for multiple
                 // windows in the same type layer.
@@ -5098,6 +5168,8 @@
                 mSubLayer = 0;
                 mAttachedWindow = null;
                 mLayoutAttached = false;
+                mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
+                        || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
             }
 
             WindowState appWin = this;
@@ -5887,7 +5959,8 @@
                   + " mClient=" + mClient.asBinder());
             pw.println(prefix + "mAttrs=" + mAttrs);
             pw.println(prefix + "mAttachedWindow=" + mAttachedWindow
-                    + " mLayoutAttached=" + mLayoutAttached);
+                    + " mLayoutAttached=" + mLayoutAttached
+                    + " mIsImWindow=" + mIsImWindow);
             pw.println(prefix + "mBaseLayer=" + mBaseLayer
                   + " mSubLayer=" + mSubLayer
                   + " mAnimLayer=" + mLayer + "+"
@@ -6807,11 +6880,7 @@
         
         for (i=0; i<N; i++) {
             WindowState w = (WindowState)mWindows.get(i);
-            if (w.mBaseLayer == curBaseLayer) {
-                curLayer += WINDOW_LAYER_MULTIPLIER;
-                w.mLayer = curLayer;
-            } else if (w.mAttrs.type == TYPE_INPUT_METHOD
-                    || w.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
+            if (w.mBaseLayer == curBaseLayer || w.mIsImWindow) {
                 curLayer += WINDOW_LAYER_MULTIPLIER;
                 w.mLayer = curLayer;
             } else {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d2149f1..d0c2dac 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1457,6 +1457,13 @@
         return proc;
     }
 
+    private boolean isNextTransitionForward() {
+        int transit = mWindowManager.getPendingAppTransition();
+        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
+                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
+                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
+    }
+    
     private final boolean realStartActivityLocked(HistoryRecord r,
             ProcessRecord app, boolean andResume, boolean checkConfig)
             throws RemoteException {
@@ -1506,7 +1513,8 @@
                         r.task.taskId, r.shortComponentName);
             }
             app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
-                    r.info, r.icicle, results, newIntents, !andResume);
+                    r.info, r.icicle, results, newIntents, !andResume,
+                    isNextTransitionForward());
         } catch (RemoteException e) {
             if (r.launchFailed) {
                 // This is the second time we failed -- finish activity
@@ -2271,7 +2279,8 @@
                         System.identityHashCode(next),
                         next.task.taskId, next.shortComponentName);
                 
-                next.app.thread.scheduleResumeActivity(next);
+                next.app.thread.scheduleResumeActivity(next,
+                        isNextTransitionForward());
                 pauseIfSleepingLocked();
 
             } catch (Exception e) {
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 31f55c8..2d2faeb 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -1476,7 +1476,8 @@
         lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
         lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         lp.format = pixelFormat;
         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
         lp.setTitle("StatusBarExpanded");