auto import from //branches/cupcake/...@130745
diff --git a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java b/policy/com/android/internal/policy/impl/AccountUnlockScreen.java
index 98cb548..573622f3 100644
--- a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java
+++ b/policy/com/android/internal/policy/impl/AccountUnlockScreen.java
@@ -28,8 +28,10 @@
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.text.Editable;
 import android.text.InputFilter;
 import android.text.LoginFilter;
+import android.text.TextWatcher;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -47,7 +49,7 @@
  * IAccountsService.
  */
 public class AccountUnlockScreen extends RelativeLayout implements KeyguardScreen,
-        View.OnClickListener, ServiceConnection {
+        View.OnClickListener, ServiceConnection, TextWatcher {
 
 
     private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
@@ -87,8 +89,10 @@
 
         mLogin = (EditText) findViewById(R.id.login);
         mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
+        mLogin.addTextChangedListener(this);
 
         mPassword = (EditText) findViewById(R.id.password);
+        mPassword.addTextChangedListener(this);
 
         mOk = (Button) findViewById(R.id.ok);
         mOk.setOnClickListener(this);
@@ -105,6 +109,16 @@
         }
     }
 
+    public void afterTextChanged(Editable s) {
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+        mCallback.pokeWakelock();
+    }
+
     @Override
     protected boolean onRequestFocusInDescendants(int direction,
             Rect previouslyFocusedRect) {
@@ -113,6 +127,11 @@
     }
 
     /** {@inheritDoc} */
+    public boolean needsInput() {
+        return true;
+    }
+    
+    /** {@inheritDoc} */
     public void onPause() {
 
     }
@@ -132,6 +151,7 @@
 
     /** {@inheritDoc} */
     public void onClick(View v) {
+        mCallback.pokeWakelock();
         if (v == mOk) {
             if (checkPassword()) {
                 // clear out forgotten password
diff --git a/policy/com/android/internal/policy/impl/KeyguardScreen.java b/policy/com/android/internal/policy/impl/KeyguardScreen.java
index 739664b..bbb6875 100644
--- a/policy/com/android/internal/policy/impl/KeyguardScreen.java
+++ b/policy/com/android/internal/policy/impl/KeyguardScreen.java
@@ -23,6 +23,12 @@
 public interface KeyguardScreen {
 
     /**
+     * Return true if your view needs input, so should allow the soft
+     * keyboard to be displayed.
+     */
+    boolean needsInput();
+    
+    /**
      * This screen is no longer in front of the user.
      */
     void onPause();
@@ -36,5 +42,4 @@
      * This view is going away; a hook to do cleanup.
      */
     void cleanUp();
-
 }
diff --git a/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 4671957..3a25d38 100644
--- a/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -375,12 +375,12 @@
     }
 
     /**
-     * Is the keyboard currently open?
+     * Is the (hard) keyboard currently open?
      */
     boolean queryKeyboardOpen() {
         final Configuration configuration = mContext.getResources().getConfiguration();
 
-        return configuration.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO;
+        return configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
     }
 
     /**
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/com/android/internal/policy/impl/KeyguardViewManager.java
index f5dd3e5..567c912 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -19,6 +19,7 @@
 import com.android.internal.R;
 
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.graphics.PixelFormat;
 import android.graphics.Canvas;
 import android.util.Log;
@@ -34,7 +35,7 @@
  * the wake lock and report that the keyguard is done, which is in turn,
  * reported to this class by the current {@link KeyguardViewBase}.
  */
-public class KeyguardViewManager {
+public class KeyguardViewManager implements KeyguardWindowController {
     private final static boolean DEBUG = false;
     private static String TAG = "KeyguardViewManager";
 
@@ -45,6 +46,9 @@
 
     private final KeyguardUpdateMonitor mUpdateMonitor;
 
+    private WindowManager.LayoutParams mWindowLayoutParams;
+    private boolean mNeedsInput = false;
+    
     private FrameLayout mKeyguardHost;
     private KeyguardViewBase mKeyguardView;
 
@@ -97,19 +101,27 @@
 
             final int stretch = ViewGroup.LayoutParams.FILL_PARENT;
             int flags = WindowManager.LayoutParams.FLAG_DITHER
-                    | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+                    /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/
+                    | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
+            if (!mNeedsInput) {
+                flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            }
             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                     stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,
                     flags, PixelFormat.OPAQUE);
+            lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
+            lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
+            lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
             lp.setTitle("Keyguard");
+            mWindowLayoutParams = lp;
 
             mViewManager.addView(mKeyguardHost, lp);
         }
 
         if (mKeyguardView == null) {
             if (DEBUG) Log.d(TAG, "keyguard view is null, creating it...");
-            mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor);
+            mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);
             mKeyguardView.setId(R.id.lock_screen);
             mKeyguardView.setCallback(mCallback);
 
@@ -128,6 +140,20 @@
         mKeyguardView.requestFocus();
     }
 
+    public void setNeedsInput(boolean needsInput) {
+        mNeedsInput = needsInput;
+        if (mWindowLayoutParams != null) {
+            if (needsInput) {
+                mWindowLayoutParams.flags &=
+                    ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            } else {
+                mWindowLayoutParams.flags |=
+                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            }
+            mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+        }
+    }
+    
     /**
      * Reset the state of the view.
      */
@@ -183,7 +209,7 @@
     public synchronized void hide() {
         if (DEBUG) Log.d(TAG, "hide()");
         if (mKeyguardHost != null) {
-            mKeyguardHost.setVisibility(View.INVISIBLE);
+            mKeyguardHost.setVisibility(View.GONE);
             if (mKeyguardView != null) {
                 mKeyguardHost.removeView(mKeyguardView);
                 mKeyguardView.cleanUp();
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewProperties.java b/policy/com/android/internal/policy/impl/KeyguardViewProperties.java
index a449653..bda08eb 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewProperties.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewProperties.java
@@ -29,9 +29,12 @@
      * Create a keyguard view.
      * @param context the context to use when creating the view.
      * @param updateMonitor configuration may be based on this.
+     * @param controller for talking back with the containing window.
      * @return the view.
      */
-    KeyguardViewBase createKeyguardView(Context context, KeyguardUpdateMonitor updateMonitor);
+    KeyguardViewBase createKeyguardView(Context context,
+            KeyguardUpdateMonitor updateMonitor,
+            KeyguardWindowController controller);
 
     /**
      * Would the keyguard be secure right now?
diff --git a/policy/com/android/internal/policy/impl/KeyguardWindowController.java b/policy/com/android/internal/policy/impl/KeyguardWindowController.java
new file mode 100644
index 0000000..4ad48fb
--- /dev/null
+++ b/policy/com/android/internal/policy/impl/KeyguardWindowController.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl;
+
+/**
+ * Interface passed to the keyguard view, for it to call up to control
+ * its containing window.
+ */
+public interface KeyguardWindowController {
+    /**
+     * Control whether the window needs input -- that is if it has
+     * text fields and thus should allow input method interaction.
+     */
+    void setNeedsInput(boolean needsInput);
+}
diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 4ff87e3..1ec7e150 100644
--- a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -53,6 +53,8 @@
     private static final String TAG = "LockPatternKeyguardView";
 
     private final KeyguardUpdateMonitor mUpdateMonitor;
+    private final KeyguardWindowController mWindowController;
+    
     private View mLockScreen;
     private View mUnlockScreen;
 
@@ -147,7 +149,8 @@
     public LockPatternKeyguardView(
             Context context,
             KeyguardUpdateMonitor updateMonitor,
-            LockPatternUtils lockPatternUtils) {
+            LockPatternUtils lockPatternUtils,
+            KeyguardWindowController controller) {
         super(context);
         
         asyncCheckForAccount();
@@ -157,6 +160,7 @@
 
         mUpdateMonitor = updateMonitor;
         mLockPatternUtils = lockPatternUtils;
+        mWindowController = controller;
 
         mMode = getInitialMode();
         
@@ -417,6 +421,8 @@
         goneScreen.setVisibility(View.GONE);
         visibleScreen.setVisibility(View.VISIBLE);
 
+        mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());
+        
         if (!visibleScreen.requestFocus()) {
             throw new IllegalStateException("keyguard screen must be able to take "
                     + "focus when shown " + visibleScreen.getClass().getCanonicalName());
diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
index 697c038..4e0cf09 100644
--- a/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
+++ b/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
@@ -43,8 +43,10 @@
     }
 
     public KeyguardViewBase createKeyguardView(Context context,
-            KeyguardUpdateMonitor updateMonitor) {
-        return new LockPatternKeyguardView(context, updateMonitor, mLockPatternUtils);
+            KeyguardUpdateMonitor updateMonitor,
+            KeyguardWindowController controller) {
+        return new LockPatternKeyguardView(context, updateMonitor,
+                mLockPatternUtils, controller);
     }
 
     public boolean isSecure() {
diff --git a/policy/com/android/internal/policy/impl/LockScreen.java b/policy/com/android/internal/policy/impl/LockScreen.java
index 0825c3b..700c9eb 100644
--- a/policy/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/com/android/internal/policy/impl/LockScreen.java
@@ -351,6 +351,11 @@
 
 
     /** {@inheritDoc} */
+    public boolean needsInput() {
+        return false;
+    }
+    
+    /** {@inheritDoc} */
     public void onPause() {
 
     }
diff --git a/policy/com/android/internal/policy/impl/PhoneWindow.java b/policy/com/android/internal/policy/impl/PhoneWindow.java
index 80a2120..6afe528 100644
--- a/policy/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindow.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -67,6 +66,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
@@ -149,39 +149,52 @@
     
     private boolean mSearchKeyDownReceived;
     
-    private final Handler mKeycodeCallTimeoutHandler = new Handler() {
+    private boolean mKeycodeCallTimeoutActive = false;
+
+    private boolean mKeycodeCameraTimeoutActive = false;
+
+    static final int MSG_MENU_LONG_PRESS = 1;
+    static final int MSG_CALL_LONG_PRESS = 2;
+    static final int MSG_CAMERA_LONG_PRESS = 3;
+    
+    private final Handler mKeycodeMenuTimeoutHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
-            if (!mKeycodeCallTimeoutActive) return;
-            mKeycodeCallTimeoutActive = false;
-            // launch the VoiceDialer
-            Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            try {
-                getContext().startActivity(intent);
-            } catch (ActivityNotFoundException e) {
-                startCallActivity();
+            switch (msg.what) {
+                case MSG_MENU_LONG_PRESS: {
+                    if (mPanelChordingKey == 0) return;
+                    mPanelChordingKey = 0;
+                    InputMethodManager imm = (InputMethodManager)
+                            getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                    if (imm != null) {
+                        imm.showSoftInputUnchecked(InputMethodManager.SHOW_FORCED);
+                    }
+                } break;
+                case MSG_CALL_LONG_PRESS: {
+                    if (!mKeycodeCallTimeoutActive) return;
+                    mKeycodeCallTimeoutActive = false;
+                    // launch the VoiceDialer
+                    Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    try {
+                        sendCloseSystemWindows();
+                        getContext().startActivity(intent);
+                    } catch (ActivityNotFoundException e) {
+                        startCallActivity();
+                    }
+                } break;
+                case MSG_CAMERA_LONG_PRESS: {
+                    if (!mKeycodeCameraTimeoutActive) return;
+                    mKeycodeCameraTimeoutActive = false;
+                    // Broadcast an intent that the Camera button was longpressed
+                    Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
+                    intent.putExtra(Intent.EXTRA_KEY_EVENT, (KeyEvent) msg.obj);
+                    getContext().sendOrderedBroadcast(intent, null);
+                } break;
             }
         }
     };
-    private boolean mKeycodeCallTimeoutActive = false;
-
-    // Ideally the call and camera buttons would share a common base class, and each implement their
-    // own onShortPress() and onLongPress() methods, but to reduce the chance of regressions I'm
-    // keeping them separate for now.
-    private final Handler mKeycodeCameraTimeoutHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            if (!mKeycodeCameraTimeoutActive) return;
-            mKeycodeCameraTimeoutActive = false;
-            // Broadcast an intent that the Camera button was longpressed
-            Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
-            intent.putExtra(Intent.EXTRA_KEY_EVENT, (KeyEvent) msg.obj);
-            getContext().sendOrderedBroadcast(intent, null);
-        }
-    };
-    private boolean mKeycodeCameraTimeoutActive = false;
-
+    
     public PhoneWindow(Context context) {
         super(context);
         mLayoutInflater = LayoutInflater.from(context);
@@ -566,6 +579,13 @@
 
         PanelFeatureState st = getPanelState(featureId, true);
         if (!st.isOpen) {
+            if (getContext().getResources().getConfiguration().keyboard
+                    == Configuration.KEYBOARD_NOKEYS) {
+                mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS);
+                mKeycodeMenuTimeoutHandler.sendMessageDelayed(
+                        mKeycodeMenuTimeoutHandler.obtainMessage(MSG_MENU_LONG_PRESS),
+                        ViewConfiguration.getLongPressTimeout());
+            }
             return preparePanel(st, event);
         }
 
@@ -579,37 +599,40 @@
      */
     public final void onKeyUpPanel(int featureId, KeyEvent event) {
         // The panel key was released, so clear the chording key
-        mPanelChordingKey = 0;
-
-        boolean playSoundEffect = false;
-        PanelFeatureState st = getPanelState(featureId, true);
-        if (st.isOpen || st.isHandled) {
-         
-            // Play the sound effect if the user closed an open menu (and not if
-            // they just released a menu shortcut)
-            playSoundEffect = st.isOpen;
-
-            // Close menu
-            closePanel(st, true);
-            
-        } else if (st.isPrepared) {
-            
-            // Write 'menu opened' to event log
-            EventLog.writeEvent(50001, 0);
-            
-            // Show menu
-            openPanel(st, event);
-            
-            playSoundEffect = true;
-        }
-
-        if (playSoundEffect) {
-            AudioManager audioManager = (AudioManager) getContext().getSystemService(
-                    Context.AUDIO_SERVICE);
-            if (audioManager != null) {
-                audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
-            } else {
-                Log.w(TAG, "Couldn't get audio manager");
+        if (mPanelChordingKey != 0) {
+            mPanelChordingKey = 0;
+            mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS);
+    
+            boolean playSoundEffect = false;
+            PanelFeatureState st = getPanelState(featureId, true);
+            if (st.isOpen || st.isHandled) {
+             
+                // Play the sound effect if the user closed an open menu (and not if
+                // they just released a menu shortcut)
+                playSoundEffect = st.isOpen;
+    
+                // Close menu
+                closePanel(st, true);
+                
+            } else if (st.isPrepared) {
+                
+                // Write 'menu opened' to event log
+                EventLog.writeEvent(50001, 0);
+                
+                // Show menu
+                openPanel(st, event);
+                
+                playSoundEffect = true;
+            }
+    
+            if (playSoundEffect) {
+                AudioManager audioManager = (AudioManager) getContext().getSystemService(
+                        Context.AUDIO_SERVICE);
+                if (audioManager != null) {
+                    audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
+                } else {
+                    Log.w(TAG, "Couldn't get audio manager");
+                }
             }
         }
     }
@@ -1155,10 +1178,10 @@
                 }
                 if (event.getRepeatCount() > 0) break;
                 mKeycodeCameraTimeoutActive = true;
-                mKeycodeCameraTimeoutHandler.removeMessages(0);
-                Message message = mKeycodeCameraTimeoutHandler.obtainMessage(0);
+                mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS);
+                Message message = mKeycodeMenuTimeoutHandler.obtainMessage(MSG_CAMERA_LONG_PRESS);
                 message.obj = event;
-                mKeycodeCameraTimeoutHandler.sendMessageDelayed(message,
+                mKeycodeMenuTimeoutHandler.sendMessageDelayed(message,
                         ViewConfiguration.getLongPressTimeout());
                 return true;
             }
@@ -1191,9 +1214,9 @@
                 }
                 if (event.getRepeatCount() > 0) break;
                 mKeycodeCallTimeoutActive = true;
-                mKeycodeCallTimeoutHandler.removeMessages(0);
-                mKeycodeCallTimeoutHandler.sendMessageDelayed(
-                        mKeycodeCallTimeoutHandler.obtainMessage(0),
+                mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS);
+                mKeycodeMenuTimeoutHandler.sendMessageDelayed(
+                        mKeycodeMenuTimeoutHandler.obtainMessage(MSG_CALL_LONG_PRESS),
                         ViewConfiguration.getLongPressTimeout());
                 return true;
             }
@@ -1269,7 +1292,7 @@
                     break;
                 }
                 if (event.getRepeatCount() > 0) break; // Can a key up event repeat?
-                mKeycodeCameraTimeoutHandler.removeMessages(0);
+                mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS);
                 if (!mKeycodeCameraTimeoutActive) break;
                 mKeycodeCameraTimeoutActive = false;
                 // Add short press behavior here if desired
@@ -1281,7 +1304,7 @@
                     break;
                 }
                 if (event.getRepeatCount() > 0) break;
-                mKeycodeCallTimeoutHandler.removeMessages(0);
+                mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS);
                 if (!mKeycodeCallTimeoutActive) break;
                 mKeycodeCallTimeoutActive = false;
                 startCallActivity();
@@ -1307,6 +1330,7 @@
     }
 
     private void startCallActivity() {
+        sendCloseSystemWindows();
         Intent intent = new Intent(Intent.ACTION_CALL_BUTTON);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         getContext().startActivity(intent);
@@ -1854,9 +1878,10 @@
             super.onWindowFocusChanged(hasWindowFocus);
             
             // no KEYCODE_CALL events active across focus changes
-            mKeycodeCallTimeoutHandler.removeMessages(0);
+            mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS);
+            mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS);
+            mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS);
             mKeycodeCallTimeoutActive = false;
-            mKeycodeCameraTimeoutHandler.removeMessages(0);
             mKeycodeCameraTimeoutActive = false;
 
             // If the user is chording a menu shortcut, release the chord since
@@ -1958,9 +1983,10 @@
                     android.R.styleable.Window_backgroundDimAmount, 0.5f);
         }
 
-        params.windowAnimations = a.getResourceId(
-                com.android.internal.R.styleable.Window_windowAnimationStyle,
-                params.windowAnimations);
+        if (params.windowAnimations == 0) {
+            params.windowAnimations = a.getResourceId(
+                    com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
+        }
         
         // The rest are only done if this window is not embedded; otherwise,
         // the values are inherited from our container.
@@ -2614,4 +2640,12 @@
             return true;
         }
     }
+
+    void sendCloseSystemWindows() {
+        PhoneWindowManager.sendCloseSystemWindows(getContext(), null);
+    }
+
+    void sendCloseSystemWindows(String reason) {
+        PhoneWindowManager.sendCloseSystemWindows(getContext(), reason);
+    }
 }
diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
index 346470f..172ab35 100644
--- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -39,6 +39,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Vibrator;
 import android.provider.Settings;
 
 import com.android.internal.policy.PolicyManager;
@@ -138,13 +139,18 @@
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
     static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
 
+    // Vibrator pattern for indicating when the orientation has changed
+    private static final long[] VIBE_PATTERN = {0, 1, 40, 41};
+    
     Context mContext;
     IWindowManager mWindowManager;
     LocalPowerManager mPowerManager;
+    Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
 
     /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */
     boolean mEnableShiftMenuBugReports = false;
     
+    boolean mSafeMode;
     WindowState mStatusBar = null;
     WindowState mSearchBar = null;
     WindowState mKeyguard = null;
@@ -732,6 +738,11 @@
         return keyguardIsShowingTq() || inKeyguardRestrictedKeyInputMode();
     }
 
+    private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
+            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
+            WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
+        };
+
     /** {@inheritDoc} */
     public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, 
             int repeatCount) {
@@ -739,7 +750,7 @@
 
         if (false) {
             Log.d(TAG, "interceptKeyTi code=" + code + " down=" + down + " repeatCount="
-                    + repeatCount + " keyguardOn=" + keyguardOn);
+                    + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed);
         }
 
         // Clear a pending HOME longpress if the user releases Home
@@ -795,15 +806,19 @@
             // right now to interact with applications.
             WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
             if (attrs != null) {
-                int type = attrs.type;
-                if (type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
-                        && type <= WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
-                    // Only do this once, so home-key-longpress doesn't close itself
-                    if (repeatCount == 0 && down) {
-                		sendCloseSystemWindows();
-                    }
+                final int type = attrs.type;
+                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
+                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
+                    // the "app" is keyguard, so give it the key
                     return false;
                 }
+                final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
+                for (int i=0; i<typeCount; i++) {
+                    if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
+                        // don't do anything, but also don't pass it to the app
+                        return true;
+                    }
+                }
             }
             
             if (down && repeatCount == 0) {
@@ -1160,29 +1175,31 @@
             && win.fillsScreenLw(mW, mH, true)
             && win.isVisibleLw()) {
             mTopFullscreenOpaqueWindowState = win;
-        } else if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
+        } else if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0
+                && win.isVisibleLw()) {
             mForceStatusBar = true;
         }
     }
 
     /** {@inheritDoc} */
     public boolean finishAnimationLw() {
+        boolean changed = false;
         if (mStatusBar != null) {
             if (mForceStatusBar) {
-                mStatusBar.showLw(true);
+                changed |= mStatusBar.showLw(true);
             } else if (mTopFullscreenOpaqueWindowState != null) {
                WindowManager.LayoutParams lp =
                    mTopFullscreenOpaqueWindowState.getAttrs();
                boolean hideStatusBar =
                    (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
                if (hideStatusBar) {
-                   mStatusBar.hideLw(true);
+                   changed |= mStatusBar.hideLw(true);
                } else {
-                   mStatusBar.showLw(true);
+                   changed |= mStatusBar.showLw(true);
                }
            }
         }
-       return false;
+       return changed;
     }
 
     /** {@inheritDoc} */
@@ -1416,10 +1433,12 @@
         }
 
         public void run() {
-            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
-            intent.putExtra(Intent.EXTRA_KEY_EVENT, mKeyEvent);
-            mContext.sendOrderedBroadcast(intent, null, mBroadcastDone,
-                    mHandler, Activity.RESULT_OK, null, null);
+            if (ActivityManagerNative.isSystemReady()) {
+                Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+                intent.putExtra(Intent.EXTRA_KEY_EVENT, mKeyEvent);
+                mContext.sendOrderedBroadcast(intent, null, mBroadcastDone,
+                        mHandler, Activity.RESULT_OK, null, null);
+            }
         }
     }
 
@@ -1501,19 +1520,26 @@
         sendCloseSystemWindows();
     }
 
-    private void sendCloseSystemWindows() {
-        sendCloseSystemWindows(null);
+    void sendCloseSystemWindows() {
+        sendCloseSystemWindows(mContext, null);
     }
 
-    private void sendCloseSystemWindows(String reason) {
-        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        if (reason != null) {
-            intent.putExtra(SYSTEM_DIALOG_REASON_KEY, reason);
+    void sendCloseSystemWindows(String reason) {
+        sendCloseSystemWindows(mContext, reason);
+    }
+
+    static void sendCloseSystemWindows(Context context, String reason) {
+        if (ActivityManagerNative.isSystemReady()) {
+            Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+            if (reason != null) {
+                intent.putExtra(SYSTEM_DIALOG_REASON_KEY, reason);
+            }
+            context.sendBroadcast(intent);
         }
-        mContext.sendBroadcast(intent);
     }
 
-    public int rotationForOrientation(int orientation) {
+    public int rotationForOrientation(int orientation, int lastRotation,
+            boolean displayEnabled) {
         switch (orientation) {
             case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
                 //always return landscape if orientation set to landscape
@@ -1530,18 +1556,32 @@
         } else {
             if (useSensorForOrientation()) {
                 // If the user has enabled auto rotation by default, do it.
-                return mSensorRotation >= 0 ? mSensorRotation : Surface.ROTATION_0;
+                int rotation = mSensorRotation >= 0 ? mSensorRotation : Surface.ROTATION_0;
+                if (displayEnabled && rotation != lastRotation) {
+                    mVibrator.vibrate(VIBE_PATTERN, -1);
+                }
+                return rotation;
             }
             return Surface.ROTATION_0;
         }
     }
+
+    public boolean detectSafeMode() {
+        try {
+            int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
+            mSafeMode = menuState > 0;
+            Log.i(TAG, "Menu key state: " + menuState + " safeMode=" + mSafeMode);
+            return mSafeMode;
+        } catch (RemoteException e) {
+            // Doom! (it's also local)
+            throw new RuntimeException("window manager dead");
+        }
+    }
     
     /** {@inheritDoc} */
     public void systemReady() {
         try {
-            int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
-            Log.i(TAG, "Menu key state: " + menuState);
-            if (menuState > 0) {
+            if (mSafeMode) {
                 // If the user is holding the menu key code, then we are
                 // going to boot into safe mode.
                 ActivityManagerNative.getDefault().enterSafeMode();
@@ -1550,11 +1590,13 @@
             mKeyguardMediator.onSystemReady();
             android.os.SystemProperties.set("dev.bootcomplete", "1"); 
             updateOrientationListener();
+            mVibrator = new Vibrator();
         } catch (RemoteException e) {
             // Ignore
         }
     }
-    
+   
+
     /** {@inheritDoc} */
     public void enableScreenAfterBoot() {
         readLidState();
diff --git a/policy/com/android/internal/policy/impl/SimUnlockScreen.java b/policy/com/android/internal/policy/impl/SimUnlockScreen.java
index fceec5f..9453212 100644
--- a/policy/com/android/internal/policy/impl/SimUnlockScreen.java
+++ b/policy/com/android/internal/policy/impl/SimUnlockScreen.java
@@ -93,6 +93,11 @@
     }
 
     /** {@inheritDoc} */
+    public boolean needsInput() {
+        return true;
+    }
+    
+    /** {@inheritDoc} */
     public void onPause() {
 
     }
diff --git a/policy/com/android/internal/policy/impl/UnlockScreen.java b/policy/com/android/internal/policy/impl/UnlockScreen.java
index 65ab439..16208d9 100644
--- a/policy/com/android/internal/policy/impl/UnlockScreen.java
+++ b/policy/com/android/internal/policy/impl/UnlockScreen.java
@@ -230,6 +230,11 @@
     public void onKeyboardChange(boolean isKeyboardOpen) {}
 
     /** {@inheritDoc} */
+    public boolean needsInput() {
+        return false;
+    }
+    
+    /** {@inheritDoc} */
     public void onPause() {
         if (mCountdownTimer != null) {
             mCountdownTimer.cancel();