android-2.1_r1 snapshot
diff --git a/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 58905a10..3483405 100644
--- a/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -25,6 +25,7 @@
 import static android.os.BatteryManager.BATTERY_STATUS_CHARGING;
 import static android.os.BatteryManager.BATTERY_STATUS_FULL;
 import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import android.media.AudioManager;
 import android.os.Handler;
 import android.os.Message;
 import android.provider.Settings;
@@ -69,9 +70,9 @@
     private boolean mKeyguardBypassEnabled;
 
     private boolean mDevicePluggedIn;
-    
+
     private boolean mDeviceProvisioned;
-    
+
     private int mBatteryLevel;
 
     private CharSequence mTelephonyPlmn;
@@ -86,7 +87,7 @@
     private ArrayList<InfoCallback> mInfoCallbacks = Lists.newArrayList();
     private ArrayList<SimStateCallback> mSimStateCallbacks = Lists.newArrayList();
     private ContentObserver mContentObserver;
-    
+
 
     // messages for the handler
     private static final int MSG_CONFIGURATION_CHANGED = 300;
@@ -94,14 +95,15 @@
     private static final int MSG_BATTERY_UPDATE = 302;
     private static final int MSG_CARRIER_INFO_UPDATE = 303;
     private static final int MSG_SIM_STATE_CHANGE = 304;
+    private static final int MSG_RINGER_MODE_CHANGED = 305;
 
 
     /**
-     * When we receive a 
-     * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast, 
+     * When we receive a
+     * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
      * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
      * we need a single object to pass to the handler.  This class helps decode
-     * the intent and provide a {@link SimCard.State} result. 
+     * the intent and provide a {@link SimCard.State} result.
      */
     private static class SimArgs {
 
@@ -140,7 +142,7 @@
 
     public KeyguardUpdateMonitor(Context context) {
         mContext = context;
-        
+
         mHandler = new Handler() {
             @Override
             public void handleMessage(Message msg) {
@@ -160,6 +162,9 @@
                     case MSG_SIM_STATE_CHANGE:
                         handleSimStateChange((SimArgs) msg.obj);
                         break;
+                    case MSG_RINGER_MODE_CHANGED:
+                        handleRingerModeChange(msg.arg1);
+                        break;
                 }
             }
         };
@@ -169,7 +174,7 @@
 
         mDeviceProvisioned = Settings.Secure.getInt(
                 mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
-     
+
         // Since device can't be un-provisioned, we only need to register a content observer
         // to update mDeviceProvisioned when we are...
         if (!mDeviceProvisioned) {
@@ -177,7 +182,7 @@
                 @Override
                 public void onChange(boolean selfChange) {
                     super.onChange(selfChange);
-                    mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(), 
+                    mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(),
                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
                     if (mDeviceProvisioned && mContentObserver != null) {
                         // We don't need the observer anymore...
@@ -187,17 +192,17 @@
                     if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
                 }
             };
-            
+
             mContext.getContentResolver().registerContentObserver(
                     Settings.Secure.getUriFor(Settings.Secure.DEVICE_PROVISIONED),
                     false, mContentObserver);
-            
+
             // prevent a race condition between where we check the flag and where we register the
             // observer by grabbing the value once again...
-            mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(), 
+            mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
         }
-        
+
         mInPortrait = queryInPortrait();
         mKeyboardOpen = queryKeyboardOpen();
 
@@ -217,6 +222,7 @@
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         filter.addAction(SPN_STRINGS_UPDATED_ACTION);
+        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         context.registerReceiver(new BroadcastReceiver() {
 
             public void onReceive(Context context, Intent intent) {
@@ -242,15 +248,25 @@
                             pluggedInStatus,
                             batteryLevel);
                     mHandler.sendMessage(msg);
-                } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)){
+                } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
                     mHandler.sendMessage(mHandler.obtainMessage(
                             MSG_SIM_STATE_CHANGE,
                             new SimArgs(intent)));
+                } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
+                    mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
+                            intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
                 }
             }
         }, filter);
     }
 
+    protected void handleRingerModeChange(int mode) {
+        if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
+        for (int i = 0; i < mInfoCallbacks.size(); i++) {
+            mInfoCallbacks.get(i).onRingerModeChanged(mode);
+        }
+    }
+
     /**
      * Handle {@link #MSG_CONFIGURATION_CHANGED}
      */
@@ -443,7 +459,7 @@
     }
 
     /**
-     * Callback for general information releveant to lock screen.
+     * Callback for general information relevant to lock screen.
      */
     interface InfoCallback {
         void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel);
@@ -455,6 +471,13 @@
          * @param spn The service provider name.  May be null if it shouldn't be displayed.
          */
         void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn);
+
+        /**
+         * Called when the ringer mode changes.
+         * @param state the current ringer state, as defined in
+         * {@link AudioManager#RINGER_MODE_CHANGED_ACTION}
+         */
+        void onRingerModeChanged(int state);
     }
 
     /**
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/com/android/internal/policy/impl/KeyguardViewManager.java
index bac2fcad..d4dc429 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -92,7 +92,7 @@
      * lazily.
      */
     public synchronized void show() {
-        if (DEBUG) Log.d(TAG, "show()");
+        if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
 
         if (mKeyguardHost == null) {
             if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
index f5591b2..8d71146 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -105,6 +105,7 @@
     private static final int KEYGUARD_DONE = 9;
     private static final int KEYGUARD_DONE_DRAWING = 10;
     private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
+    private static final int SET_HIDDEN = 12;
     
     /**
      * The default amount of time we stay awake (used for all key input)
@@ -279,8 +280,9 @@
 
     /**
      * Called to let us know the screen was turned off.
-     * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER} or
-     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}.
+     * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},
+     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or
+     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
      */
     public void onScreenTurnedOff(int why) {
         synchronized (this) {
@@ -311,6 +313,8 @@
                         sender);
                 if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = " 
                                  + mDelayedShowingSequence);
+            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
+                // Do not enable the keyguard if the prox sensor forced the screen off.
             } else {
                 doKeyguard();
             }
@@ -421,13 +425,31 @@
     }
 
     /**
+     * Is the keyguard currently showing and not being force hidden?
+     */
+    public boolean isShowingAndNotHidden() {
+        return mShowing && !mHidden;
+    }
+
+    /**
      * Notify us when the keyguard is hidden by another window
      */
     public void setHidden(boolean isHidden) {
         if (DEBUG) Log.d(TAG, "setHidden " + isHidden);
+        mHandler.removeMessages(SET_HIDDEN);
+        Message msg = mHandler.obtainMessage(SET_HIDDEN, (isHidden ? 1 : 0), 0);
+        mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Handles SET_HIDDEN message sent by setHidden()
+     */
+    private void handleSetHidden(boolean isHidden) {
         synchronized (KeyguardViewMediator.this) {
-            mHidden = isHidden;
-            adjustUserActivityLocked();
+            if (mHidden != isHidden) {
+                mHidden = isHidden;
+                adjustUserActivityLocked();
+            }
         }
     }
 
@@ -812,6 +834,9 @@
                 case KEYGUARD_DONE_AUTHENTICATING:
                     keyguardDone(true);
                     return;
+                case SET_HIDDEN:
+                    handleSetHidden(msg.arg1 != 0);
+                    break;
             }
         }
     };
diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 0ebd945..00dc929 100644
--- a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -160,7 +160,10 @@
         } catch (AuthenticatorException e) {
         }
         mEnableFallback = !hasSAMLAccount;
-        if (mUnlockScreen instanceof UnlockScreen) {
+
+        if (mUnlockScreen == null) {
+            Log.w(TAG, "no unlock screen when receiving AccountManager information");
+        } else if (mUnlockScreen instanceof UnlockScreen) {
             ((UnlockScreen)mUnlockScreen).setEnableFallback(true);
         }
     }
@@ -179,18 +182,6 @@
             KeyguardWindowController controller) {
         super(context);
 
-        final boolean hasAccount = AccountManager.get(context).getAccounts().length > 0;
-        if (hasAccount) {
-            /* If we have a SAML account which requires web login we can not use the
-             fallback screen UI to ask the user for credentials.
-             For now we will disable fallback screen in this case.
-             Ultimately we could consider bringing up a web login from GLS
-             but need to make sure that it will work in the "locked screen" mode. */
-            String[] features = new String[] {"saml"};
-            AccountManager.get(context).getAccountsByTypeAndFeatures(
-                    "com.google", features, this, null);
-        }
-        
         mEnableFallback = false;
 
         mRequiresSim =
@@ -275,6 +266,9 @@
             public void reportFailedPatternAttempt() {
                 mUpdateMonitor.reportFailedAttempt();
                 final int failedAttempts = mUpdateMonitor.getFailedAttempts();
+                if (DEBUG) Log.d(TAG, 
+                    "reportFailedPatternAttempt: #" + failedAttempts +
+                    " (enableFallback=" + mEnableFallback + ")");
                 if (mEnableFallback && failedAttempts ==
                         (LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
                                 - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
@@ -313,8 +307,28 @@
         mLockScreen = createLockScreen();
         addView(mLockScreen);
         final UnlockMode unlockMode = getUnlockMode();
+        if (DEBUG) Log.d(TAG, 
+            "LockPatternKeyguardView ctor: about to createUnlockScreenFor; mEnableFallback="
+            + mEnableFallback);
         mUnlockScreen = createUnlockScreenFor(unlockMode);
         mUnlockScreenMode = unlockMode;
+
+        // Ask the account manager if we have an account that can be used as a
+        // fallback in case the user forgets his pattern. The response comes
+        // back in run() below; don't bother asking until you've called
+        // createUnlockScreenFor(), else the information will go unused.
+        final boolean hasAccount = AccountManager.get(context).getAccounts().length > 0;
+        if (hasAccount) {
+            /* If we have a SAML account which requires web login we can not use the
+             fallback screen UI to ask the user for credentials.
+             For now we will disable fallback screen in this case.
+             Ultimately we could consider bringing up a web login from GLS
+             but need to make sure that it will work in the "locked screen" mode. */
+            String[] features = new String[] {"saml"};
+            AccountManager.get(context).getAccountsByTypeAndFeatures(
+                    "com.google", features, this, null);
+        }
+
         addView(mUnlockScreen);
         updateScreen(mMode);
     }
@@ -475,6 +489,8 @@
                     mUpdateMonitor,
                     mKeyguardScreenCallback,
                     mUpdateMonitor.getFailedAttempts());
+            if (DEBUG) Log.d(TAG,
+                "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);
             view.setEnableFallback(mEnableFallback);
             return view;
         } else if (unlockMode == UnlockMode.SimPin) {
diff --git a/policy/com/android/internal/policy/impl/LockScreen.java b/policy/com/android/internal/policy/impl/LockScreen.java
index dda5097..7514cc2 100644
--- a/policy/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/com/android/internal/policy/impl/LockScreen.java
@@ -17,8 +17,9 @@
 package com.android.internal.policy.impl;
 
 import com.android.internal.R;
+import com.android.internal.telephony.IccCard;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.RotarySelector;
+import com.android.internal.widget.SlidingTab;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -33,11 +34,8 @@
 import android.media.AudioManager;
 import android.os.SystemProperties;
 
-import com.android.internal.telephony.IccCard;
-
 import java.util.Date;
 import java.io.File;
-import java.text.SimpleDateFormat;
 
 /**
  * The screen within {@link LockPatternKeyguardView} that shows general
@@ -46,7 +44,7 @@
  */
 class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateMonitor.InfoCallback,
         KeyguardUpdateMonitor.SimStateCallback, KeyguardUpdateMonitor.ConfigurationChangeCallback,
-        RotarySelector.OnDialTriggerListener {
+        SlidingTab.OnTriggerListener {
 
     private static final boolean DBG = false;
     private static final String TAG = "LockScreen";
@@ -59,7 +57,7 @@
     private final KeyguardScreenCallback mCallback;
 
     private TextView mCarrier;
-    private RotarySelector mRotary;
+    private SlidingTab mSelector;
     private TextView mTime;
     private TextView mDate;
     private TextView mStatus1;
@@ -83,7 +81,7 @@
 
     private boolean mSilentMode;
     private AudioManager mAudioManager;
-    private java.text.DateFormat mDateFormat;
+    private String mDateFormatString;
     private java.text.DateFormat mTimeFormat;
     private boolean mCreatedInPortrait;
     private boolean mEnableMenuKeyInLockScreen;
@@ -175,13 +173,12 @@
 
         final LayoutInflater inflater = LayoutInflater.from(context);
         if (mCreatedInPortrait) {
-            inflater.inflate(R.layout.keyguard_screen_rotary_unlock, this, true);
+            inflater.inflate(R.layout.keyguard_screen_tab_unlock, this, true);
         } else {
-            inflater.inflate(R.layout.keyguard_screen_rotary_unlock_land, this, true);
+            inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true);
         }
 
         mCarrier = (TextView) findViewById(R.id.carrier);
-        mTime = (TextView) findViewById(R.id.time);
         mDate = (TextView) findViewById(R.id.date);
         mStatus1 = (TextView) findViewById(R.id.status1);
         mStatus2 = (TextView) findViewById(R.id.status2);
@@ -189,7 +186,9 @@
         mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
         mEmergencyCallButton.setText(R.string.lockscreen_emergency_call);
         mScreenLocked = (TextView) findViewById(R.id.screenLocked);
-        mRotary = (RotarySelector) findViewById(R.id.rotary);
+        mSelector = (SlidingTab) findViewById(R.id.tab_selector);
+        mSelector.setHoldAfterTrigger(true, false);
+        mSelector.setLeftHintText(R.string.lockscreen_unlock_label);
         mEmergencyCallButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 mCallback.takeEmergencyCallAction();
@@ -205,17 +204,35 @@
         updateMonitor.registerConfigurationChangeCallback(this);
 
         mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
-        mSilentMode = mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT;
+        mSilentMode = isSilentMode();
 
-        mRotary.setOnDialTriggerListener(this);
-        mRotary.setLeftHandleResource(R.drawable.ic_jog_dial_unlock);
-        mRotary.setRightHandleResource(mSilentMode ?
-                R.drawable.ic_jog_dial_sound_off :
-                R.drawable.ic_jog_dial_sound_on);
+        mSelector.setLeftTabResources(
+                R.drawable.ic_jog_dial_unlock,
+                R.drawable.jog_tab_target_green,
+                R.drawable.jog_tab_bar_left_unlock,
+                R.drawable.jog_tab_left_unlock);
+
+        updateRightTabResources();
+
+        mSelector.setOnTriggerListener(this);
 
         resetStatusInfo(updateMonitor);
     }
 
+    private boolean isSilentMode() {
+        return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT;
+    }
+
+    private void updateRightTabResources() {
+        mSelector.setRightTabResources(
+                mSilentMode ? R.drawable.ic_jog_dial_sound_off : R.drawable.ic_jog_dial_sound_on,
+                mSilentMode ? R.drawable.jog_tab_target_yellow : R.drawable.jog_tab_target_gray,
+                mSilentMode ? R.drawable.jog_tab_bar_right_sound_on
+                        : R.drawable.jog_tab_bar_right_sound_off,
+                mSilentMode ? R.drawable.jog_tab_right_sound_on
+                        : R.drawable.jog_tab_right_sound_off);
+    }
+
     private void resetStatusInfo(KeyguardUpdateMonitor updateMonitor) {
         mShowingBatteryInfo = updateMonitor.shouldShowBatteryInfo();
         mPluggedIn = updateMonitor.isDevicePluggedIn();
@@ -228,7 +245,7 @@
         refreshAlarmDisplay();
 
         mTimeFormat = DateFormat.getTimeFormat(getContext());
-        mDateFormat = getLockScreenDateFormat();
+        mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
         refreshTimeAndDateDisplay();
         updateStatusLines();
     }
@@ -242,24 +259,23 @@
     }
 
     /** {@inheritDoc} */
-    public void onDialTrigger(View v, int whichHandle) {
-        if (whichHandle == RotarySelector.OnDialTriggerListener.LEFT_HANDLE) {
+    public void onTrigger(View v, int whichHandle) {
+        if (whichHandle == SlidingTab.OnTriggerListener.LEFT_HANDLE) {
             mCallback.goToUnlockScreen();
-        } else if (whichHandle == RotarySelector.OnDialTriggerListener.RIGHT_HANDLE) {
+        } else if (whichHandle == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {
             // toggle silent mode
             mSilentMode = !mSilentMode;
             mAudioManager.setRingerMode(mSilentMode ? AudioManager.RINGER_MODE_SILENT
                         : AudioManager.RINGER_MODE_NORMAL);
-            final int handleIcon = mSilentMode ?
-                    R.drawable.ic_jog_dial_sound_off :
-                    R.drawable.ic_jog_dial_sound_on;
-            final int toastIcon = mSilentMode ?
-                    R.drawable.ic_lock_ringer_off :
-                    R.drawable.ic_lock_ringer_on;
-            mRotary.setRightHandleResource(handleIcon);
+
+            updateRightTabResources();
+
             String message = mSilentMode ?
                     getContext().getString(R.string.global_action_silent_mode_on_status) :
                     getContext().getString(R.string.global_action_silent_mode_off_status);
+
+            final int toastIcon = mSilentMode ? R.drawable.ic_lock_ringer_off
+                    : R.drawable.ic_lock_ringer_on;
             toastMessage(mScreenLocked, message, toastIcon);
             mCallback.pokeWakelock();
         }
@@ -267,7 +283,12 @@
 
     /** {@inheritDoc} */
     public void onGrabbedStateChange(View v, int grabbedState) {
-        // TODO: Update onscreen hint text based on the new state.
+        if (grabbedState == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {
+            mSilentMode = isSilentMode();
+            mSelector.setRightHintText(mSilentMode ? R.string.lockscreen_sound_on_label
+                    : R.string.lockscreen_sound_off_label);
+        }
+        mCallback.pokeWakelock();
     }
 
     /**
@@ -354,30 +375,7 @@
     }
 
     private void refreshTimeAndDateDisplay() {
-        Date now = new Date();
-        mTime.setText(mTimeFormat.format(now));
-        mDate.setText(mDateFormat.format(now));
-    }
-
-    /**
-     * @return A localized format like "Fri, Sep 18, 2009"
-     */
-    private java.text.DateFormat getLockScreenDateFormat() {
-        SimpleDateFormat adjusted = null;
-        try {
-            // this call gives us the localized order
-            final SimpleDateFormat dateFormat = (SimpleDateFormat)
-                    java.text.DateFormat.getDateInstance(java.text.DateFormat.FULL);
-            adjusted = new SimpleDateFormat(dateFormat.toPattern()
-                    .replace("MMMM", "MMM")    // we want "Sep", not "September"
-                    .replace("EEEE", "EEE"));  // we want "Fri", no "Friday"
-        } catch (ClassCastException e) {
-            // in case the library implementation changes and this throws a class cast exception
-            // or anything else that is funky
-            Log.e("LockScreen", "couldn't finnagle our custom date format :(", e);
-            return java.text.DateFormat.getDateInstance(java.text.DateFormat.MEDIUM);
-        }
-        return adjusted;
+        mDate.setText(DateFormat.format(mDateFormatString, new Date()));
     }
 
     private void updateStatusLines() {
@@ -468,7 +466,7 @@
 
                 // layout
                 mScreenLocked.setVisibility(View.VISIBLE);
-                mRotary.setVisibility(View.VISIBLE);
+                mSelector.setVisibility(View.VISIBLE);
                 mEmergencyCallButton.setVisibility(View.GONE);
                 break;
             case NetworkLocked:
@@ -478,7 +476,7 @@
 
                 // layout
                 mScreenLocked.setVisibility(View.VISIBLE);
-                mRotary.setVisibility(View.VISIBLE);
+                mSelector.setVisibility(View.VISIBLE);
                 mEmergencyCallButton.setVisibility(View.GONE);
                 break;
             case SimMissing:
@@ -488,9 +486,9 @@
 
                 // layout
                 mScreenLocked.setVisibility(View.INVISIBLE);
-                mRotary.setVisibility(View.VISIBLE);
+                mSelector.setVisibility(View.VISIBLE);
                 mEmergencyCallButton.setVisibility(View.VISIBLE);
-                putEmergencyBelow(R.id.divider);
+                putEmergencyBelow(R.id.screenLocked);
                 break;
             case SimMissingLocked:
                 // text
@@ -499,7 +497,7 @@
 
                 // layout
                 mScreenLocked.setVisibility(View.VISIBLE);
-                mRotary.setVisibility(View.GONE);
+                mSelector.setVisibility(View.GONE);
                 mEmergencyCallButton.setVisibility(View.VISIBLE);
                 putEmergencyBelow(R.id.screenLocked);
                 break;
@@ -509,7 +507,7 @@
 
                 // layout
                 mScreenLocked.setVisibility(View.INVISIBLE);
-                mRotary.setVisibility(View.VISIBLE);
+                mSelector.setVisibility(View.VISIBLE);
                 mEmergencyCallButton.setVisibility(View.GONE);
                 break;
             case SimPukLocked:
@@ -519,7 +517,7 @@
 
                 // layout
                 mScreenLocked.setVisibility(View.VISIBLE);
-                mRotary.setVisibility(View.GONE);
+                mSelector.setVisibility(View.GONE);
                 mEmergencyCallButton.setVisibility(View.VISIBLE);
                 putEmergencyBelow(R.id.screenLocked);
                 break;
@@ -563,7 +561,7 @@
     public boolean needsInput() {
         return false;
     }
-    
+
     /** {@inheritDoc} */
     public void onPause() {
 
@@ -578,4 +576,13 @@
     public void cleanUp() {
         mUpdateMonitor.removeCallback(this);
     }
+
+    /** {@inheritDoc} */
+    public void onRingerModeChanged(int state) {
+        boolean silent = AudioManager.RINGER_MODE_SILENT == state;
+        if (silent != mSilentMode) {
+            mSilentMode = silent;
+            updateRightTabResources();
+        }
+    }
 }
diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
index e57fbe8..27a42bc 100755
--- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -85,6 +85,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -94,7 +95,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
-import android.view.WindowManagerPolicy.WindowState;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.media.IAudioService;
@@ -121,25 +121,26 @@
     static final int PHONE_LAYER = 3;
     static final int SEARCH_BAR_LAYER = 4;
     static final int STATUS_BAR_PANEL_LAYER = 5;
+    static final int SYSTEM_DIALOG_LAYER = 6;
     // toasts and the plugged-in battery thing
-    static final int TOAST_LAYER = 6;
-    static final int STATUS_BAR_LAYER = 7;
+    static final int TOAST_LAYER = 7;
+    static final int STATUS_BAR_LAYER = 8;
     // SIM errors and unlock.  Not sure if this really should be in a high layer.
-    static final int PRIORITY_PHONE_LAYER = 8;
+    static final int PRIORITY_PHONE_LAYER = 9;
     // like the ANR / app crashed dialogs
-    static final int SYSTEM_ALERT_LAYER = 9;
+    static final int SYSTEM_ALERT_LAYER = 10;
     // system-level error dialogs
-    static final int SYSTEM_ERROR_LAYER = 10;
+    static final int SYSTEM_ERROR_LAYER = 11;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_LAYER = 11;
+    static final int INPUT_METHOD_LAYER = 12;
     // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_DIALOG_LAYER = 12;
+    static final int INPUT_METHOD_DIALOG_LAYER = 13;
     // the keyguard; nothing on top of these can take focus, since they are
     // responsible for power management when displayed.
-    static final int KEYGUARD_LAYER = 13;
-    static final int KEYGUARD_DIALOG_LAYER = 14;
+    static final int KEYGUARD_LAYER = 14;
+    static final int KEYGUARD_DIALOG_LAYER = 15;
     // things in here CAN NOT take focus, but are shown on top of everything else.
-    static final int SYSTEM_OVERLAY_LAYER = 15;
+    static final int SYSTEM_OVERLAY_LAYER = 16;
 
     static final int APPLICATION_MEDIA_SUBLAYER = -2;
     static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
@@ -154,6 +155,7 @@
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
     static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
+    static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
 
     final Object mLock = new Object();
     
@@ -441,7 +443,7 @@
         if (mGlobalActions == null) {
             mGlobalActions = new GlobalActions(mContext);
         }
-        final boolean keyguardShowing = mKeyguardMediator.isShowing();
+        final boolean keyguardShowing = mKeyguardMediator.isShowingAndNotHidden();
         mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
         if (keyguardShowing) {
             // since it took two seconds of long press to bring this up,
@@ -686,6 +688,8 @@
             return STATUS_BAR_LAYER;
         case TYPE_STATUS_BAR_PANEL:
             return STATUS_BAR_PANEL_LAYER;
+        case TYPE_SYSTEM_DIALOG:
+            return SYSTEM_DIALOG_LAYER;
         case TYPE_SEARCH_BAR:
             return SEARCH_BAR_LAYER;
         case TYPE_PHONE:
@@ -1108,7 +1112,7 @@
      * given the situation with the keyguard.
      */
     void launchHomeFromHotKey() {
-        if (!mHideLockScreen && mKeyguardMediator.isShowing()) {
+        if (mKeyguardMediator.isShowingAndNotHidden()) {
             // don't launch home if keyguard showing
         } else if (!mHideLockScreen && mKeyguardMediator.isInputRestricted()) {
             // when in keyguard restricted mode, must first verify unlock
@@ -1120,7 +1124,7 @@
                             ActivityManagerNative.getDefault().stopAppSwitches();
                         } catch (RemoteException e) {
                         }
-                        sendCloseSystemWindows();
+                        sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
                         startDockOrHome();
                     }
                 }
@@ -1131,7 +1135,7 @@
                 ActivityManagerNative.getDefault().stopAppSwitches();
             } catch (RemoteException e) {
             }
-            sendCloseSystemWindows();
+            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
             startDockOrHome();
         }
     }
@@ -1619,14 +1623,20 @@
     public int interceptKeyTq(RawInputEvent event, boolean screenIsOn) {
         int result = ACTION_PASS_TO_USER;
         final boolean isWakeKey = isWakeKeyTq(event);
-        final boolean keyguardShowing = keyguardIsShowingTq();
+        // If screen is off then we treat the case where the keyguard is open but hidden
+        // the same as if it were open and in front.
+        // This will prevent any keys other than the power button from waking the screen
+        // when the keyguard is hidden by another activity.
+        final boolean keyguardActive = (screenIsOn ?
+                                        mKeyguardMediator.isShowingAndNotHidden() :
+                                        mKeyguardMediator.isShowing());
 
         if (false) {
             Log.d(TAG, "interceptKeyTq event=" + event + " keycode=" + event.keycode
-                  + " screenIsOn=" + screenIsOn + " keyguardShowing=" + keyguardShowing);
+                  + " screenIsOn=" + screenIsOn + " keyguardActive=" + keyguardActive);
         }
 
-        if (keyguardShowing) {
+        if (keyguardActive) {
             if (screenIsOn) {
                 // when the screen is on, always give the event to the keyguard
                 result |= ACTION_PASS_TO_USER;
@@ -1644,14 +1654,11 @@
                     if (!mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(event.keycode)
                             && (event.keycode == KeyEvent.KEYCODE_VOLUME_DOWN
                                 || event.keycode == KeyEvent.KEYCODE_VOLUME_UP)) {
+                        // when keyguard is showing and screen off, we need
+                        // to handle the volume key for calls and  music here
                         if (isInCall()) {
-                            // if the keyguard didn't wake the device, we are in call, and
-                            // it is a volume key, turn on the screen so that the user
-                            // can more easily adjust the in call volume.
-                            mKeyguardMediator.pokeWakelock();
+                            handleVolumeKey(AudioManager.STREAM_VOICE_CALL, event.keycode);
                         } else if (isMusicActive()) {
-                            // when keyguard is showing and screen off, we need
-                            // to handle the volume key for music here
                             handleVolumeKey(AudioManager.STREAM_MUSIC, event.keycode);
                         }
                     }
@@ -1720,7 +1727,7 @@
                         mShouldTurnOffOnKeyUp = false;
                         boolean gohome = (mEndcallBehavior & ENDCALL_HOME) != 0;
                         boolean sleeps = (mEndcallBehavior & ENDCALL_SLEEPS) != 0;
-                        if (keyguardShowing
+                        if (keyguardActive
                                 || (sleeps && !gohome)
                                 || (gohome && !goHome() && sleeps)) {
                             // they must already be on the keyguad or home screen,
@@ -1923,7 +1930,7 @@
 
     /** {@inheritDoc} */
     public boolean keyguardIsShowingTq() {
-        return mKeyguardMediator.isShowing();
+        return mKeyguardMediator.isShowingAndNotHidden();
     }
 
     /** {@inheritDoc} */
@@ -1997,8 +2004,8 @@
         try {
             int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
             int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
-            int dpadState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
-            int trackballState = mWindowManager.getScancodeState(RawInputEvent.BTN_MOUSE);
+            int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
+            int trackballState = mWindowManager.getTrackballScancodeState(RawInputEvent.BTN_MOUSE);
             mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0;
             performHapticFeedbackLw(null, mSafeMode
                     ? HapticFeedbackConstants.SAFE_MODE_ENABLED
@@ -2193,7 +2200,7 @@
     public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {
         final boolean hapticsDisabled = Settings.System.getInt(mContext.getContentResolver(),
                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0;
-        if (!always && (hapticsDisabled || mKeyguardMediator.isShowing())) {
+        if (!always && (hapticsDisabled || mKeyguardMediator.isShowingAndNotHidden())) {
             return false;
         }
         switch (effectId) {
@@ -2221,7 +2228,7 @@
     }
     
     public void screenOnStoppedLw() {
-        if (!mKeyguardMediator.isShowing()) {
+        if (!mKeyguardMediator.isShowingAndNotHidden() && mPowerManager.isScreenOn()) {
             long curTime = SystemClock.uptimeMillis();
             mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT);
         }
diff --git a/policy/com/android/internal/policy/impl/UnlockScreen.java b/policy/com/android/internal/policy/impl/UnlockScreen.java
index a5032b3..e090ac5 100644
--- a/policy/com/android/internal/policy/impl/UnlockScreen.java
+++ b/policy/com/android/internal/policy/impl/UnlockScreen.java
@@ -27,6 +27,7 @@
 import android.widget.TextView;
 import android.text.format.DateFormat;
 import android.text.TextUtils;
+import android.util.Log;
 import com.android.internal.R;
 import com.android.internal.telephony.IccCard;
 import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
@@ -45,6 +46,7 @@
         implements KeyguardScreen, KeyguardUpdateMonitor.ConfigurationChangeCallback,
         KeyguardUpdateMonitor.InfoCallback, KeyguardUpdateMonitor.SimStateCallback {
 
+    private static final boolean DEBUG = false;
     private static final String TAG = "UnlockScreen";
 
     // how long before we clear the wrong pattern
@@ -71,10 +73,10 @@
 
     private boolean mCreatedInPortrait;
 
+    private String mDateFormatString;
+
     private TextView mCarrier;
-    private TextView mCenterDot;
     private TextView mDate;
-    private TextView mTime;
 
     // are we showing battery information?
     private boolean mShowingBatteryInfo = false;
@@ -102,7 +104,7 @@
      * Keeps track of the last time we poked the wake lock during dispatching
      * of the touch event, initalized to something gauranteed to make us
      * poke it when the user starts drawing the pattern.
-     * @see #dispatchTouchEvent(android.view.MotionEvent) 
+     * @see #dispatchTouchEvent(android.view.MotionEvent)
      */
     private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS;
 
@@ -162,6 +164,12 @@
         mTotalFailedPatternAttempts = totalFailedAttempts;
         mFailedPatternAttemptsSinceLastTimeout = totalFailedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
 
+        if (DEBUG) Log.d(TAG,
+            "UnlockScreen() ctor: totalFailedAttempts="
+                 + totalFailedAttempts + ", mFailedPat...="
+                 + mFailedPatternAttemptsSinceLastTimeout
+                 );
+
         if (mUpdateMonitor.isInPortrait()) {
             LayoutInflater.from(context).inflate(R.layout.keyguard_screen_unlock_portrait, this, true);
         } else {
@@ -169,11 +177,9 @@
         }
 
         mCarrier = (TextView) findViewById(R.id.carrier);
-        mCenterDot = (TextView) findViewById(R.id.centerDot);
         mDate = (TextView) findViewById(R.id.date);
-        mTime = (TextView) findViewById(R.id.time);
 
-        mCenterDot.setText("|");
+        mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
         refreshTimeAndDateDisplay();
 
         mStatus1 = (TextView) findViewById(R.id.status1);
@@ -241,9 +247,10 @@
     }
 
     public void setEnableFallback(boolean state) {
+        if (DEBUG) Log.d(TAG, "setEnableFallback(" + state + ")");
         mEnableFallback = state;
     }
-    
+
     private void resetStatusInfo() {
         mInstructions = null;
         mShowingBatteryInfo = mUpdateMonitor.shouldShowBatteryInfo();
@@ -322,9 +329,7 @@
 
 
     private void refreshTimeAndDateDisplay() {
-        Date now = new Date();
-        mTime.setText(DateFormat.getTimeFormat(getContext()).format(now));
-        mDate.setText(DateFormat.getMediumDateFormat(getContext()).format(now));
+        mDate.setText(DateFormat.format(mDateFormatString, new Date()));
     }
 
 
@@ -363,6 +368,11 @@
         mCarrier.setText(LockScreen.getCarrierString(plmn, spn));
     }
 
+    /** {@inheritDoc} */
+    public void onRingerModeChanged(int state) {
+        // not currently used
+    }
+
     // ---------- SimStateCallback
 
     /** {@inheritDoc} */
@@ -386,7 +396,7 @@
     public boolean needsInput() {
         return false;
     }
-    
+
     /** {@inheritDoc} */
     public void onPause() {
         if (mCountdownTimer != null) {
@@ -404,9 +414,9 @@
         mLockPatternView.enableInput();
         mLockPatternView.setEnabled(true);
         mLockPatternView.clearPattern();
-        
+
         // show "forgot pattern?" button if we have an alternate authentication method
-        mForgotPatternButton.setVisibility(mCallback.doesFallbackUnlockScreenExist() 
+        mForgotPatternButton.setVisibility(mCallback.doesFallbackUnlockScreenExist()
                 ? View.VISIBLE : View.INVISIBLE);
 
         // if the user is currently locked out, enforce it.
@@ -452,7 +462,7 @@
 
         public void onPatternCellAdded(List<Cell> pattern) {
             // To guard against accidental poking of the wakelock, look for
-            // the user actually trying to draw a pattern of some minimal length. 
+            // the user actually trying to draw a pattern of some minimal length.
             if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
                 mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
             }