Merge "Fix 5326463: rework sim state handling in lockscreen" into ics-factoryrom
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e3a4df9..c6b2cc7 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -936,10 +936,15 @@
      *
      * If there's currently a call in progress, the button will take them to the call
      * @param button the button to update
+     * @param the phone state:
+     *  {@link TelephonyManager#CALL_STATE_IDLE}
+     *  {@link TelephonyManager#CALL_STATE_RINGING}
+     *  {@link TelephonyManager#CALL_STATE_OFFHOOK}
      * @param showIfCapable indicates whether the button should be shown if emergency calls are
      *                      possible on the device
      */
-    public void updateEmergencyCallButtonState(Button button, boolean showIfCapable) {
+    public void updateEmergencyCallButtonState(Button button, int  phoneState,
+            boolean showIfCapable) {
         if (isEmergencyCallCapable() && showIfCapable) {
             button.setVisibility(View.VISIBLE);
         } else {
@@ -947,9 +952,8 @@
             return;
         }
 
-        int newState = TelephonyManager.getDefault().getCallState();
         int textId;
-        if (newState == TelephonyManager.CALL_STATE_OFFHOOK) {
+        if (phoneState == TelephonyManager.CALL_STATE_OFFHOOK) {
             // show "return to call" text and show phone icon
             textId = R.string.lockscreen_return_to_call;
             int phoneCallIcon = R.drawable.stat_sys_phone_call;
@@ -979,22 +983,4 @@
         }
         return false;
     }
-
-    /**
-     * Performs concentenation of PLMN/SPN
-     * @param plmn
-     * @param spn
-     * @return
-     */
-    public static CharSequence getCarrierString(CharSequence plmn, CharSequence spn) {
-        if (plmn != null && spn == null) {
-            return plmn;
-        } else if (plmn != null && spn != null) {
-            return plmn + "|" + spn;
-        } else if (plmn == null && spn != null) {
-            return spn;
-        } else {
-            return "";
-        }
-    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 61e30bf..24dce1a 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -58,6 +58,7 @@
     private static final int CARRIER_HELP_TEXT = 12;
     private static final int HELP_MESSAGE_TEXT = 13;
     private static final int OWNER_INFO = 14;
+    private static final int BATTERY_INFO = 15;
 
     private StatusMode mStatus;
     private String mDateFormatString;
@@ -84,6 +85,9 @@
     // last known battery level
     private int mBatteryLevel = 100;
 
+    // last known SIM state
+    protected State mSimState;
+
     private LockPatternUtils mLockPatternUtils;
     private KeyguardUpdateMonitor mUpdateMonitor;
     private Button mEmergencyCallButton;
@@ -98,6 +102,8 @@
     private boolean mShowingStatus;
     private KeyguardScreenCallback mCallback;
     private final boolean mShowEmergencyButtonByDefault;
+    private CharSequence mPlmn;
+    private CharSequence mSpn;
 
     private class TransientTextManager {
         private TextView mTextView;
@@ -151,6 +157,7 @@
     public KeyguardStatusViewManager(View view, KeyguardUpdateMonitor updateMonitor,
                 LockPatternUtils lockPatternUtils, KeyguardScreenCallback callback,
                 boolean showEmergencyButtonByDefault) {
+        if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()");
         mContainer = view;
         mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
         mLockPatternUtils = lockPatternUtils;
@@ -165,6 +172,12 @@
         mTransportView = (TransportControlView) findViewById(R.id.transport);
         mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
         mShowEmergencyButtonByDefault = showEmergencyButtonByDefault;
+
+        // Hide transport control view until we know we need to show it.
+        if (mTransportView != null) {
+            mTransportView.setVisibility(View.GONE);
+        }
+
         if (mEmergencyCallButton != null) {
             mEmergencyCallButton.setText(R.string.lockscreen_emergency_call);
             mEmergencyCallButton.setOnClickListener(this);
@@ -173,8 +186,6 @@
 
         mTransientTextManager = new TransientTextManager(mCarrierView);
 
-        updateEmergencyCallButtonState();
-
         resetStatusInfo();
         refreshDate();
         updateOwnerInfo();
@@ -187,10 +198,6 @@
                 v.setSelected(true);
             }
         }
-
-        // until we get an update...
-        setCarrierText(LockPatternUtils.getCarrierString(
-                mUpdateMonitor.getTelephonyPlmn(), mUpdateMonitor.getTelephonySpn()));
     }
 
     private boolean inWidgetMode() {
@@ -248,6 +255,7 @@
                 case INSTRUCTION_TEXT:
                 case CARRIER_HELP_TEXT:
                 case HELP_MESSAGE_TEXT:
+                case BATTERY_INFO:
                     mTransientTextManager.post(string, 0, INSTRUCTION_RESET_DELAY);
                     break;
 
@@ -262,15 +270,16 @@
     }
 
     public void onPause() {
+        if (DEBUG) Log.v(TAG, "onPause()");
         mUpdateMonitor.removeCallback(mInfoCallback);
         mUpdateMonitor.removeCallback(mSimStateCallback);
     }
 
     /** {@inheritDoc} */
     public void onResume() {
+        if (DEBUG) Log.v(TAG, "onResume()");
         mUpdateMonitor.registerInfoCallback(mInfoCallback);
         mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
-        updateEmergencyCallButtonState();
         resetStatusInfo();
     }
 
@@ -399,7 +408,12 @@
      * Determine the current status of the lock screen given the sim state and other stuff.
      */
     public StatusMode getStatusForIccState(IccCard.State simState) {
-        boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
+        // Since reading the SIM may take a while, we assume it is present until told otherwise.
+        if (simState == null) {
+            return StatusMode.Normal;
+        }
+
+        final boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
                 && (simState == IccCard.State.ABSENT || simState == IccCard.State.PERM_DISABLED));
 
         // Assume we're NETWORK_LOCKED if not provisioned
@@ -435,22 +449,21 @@
      *
      * @param simState
      */
-    private void updateWithSimStatus(State simState) {
-        // The emergency call button no longer appears on this screen.
-        if (DEBUG) Log.d(TAG, "updateLayout: status=" + mStatus);
+    private void updateCarrierTextWithSimStatus(State simState) {
+        if (DEBUG) Log.d(TAG, "updateCarrierTextWithSimStatus(), simState = " + simState);
 
         CharSequence carrierText = null;
         int carrierHelpTextId = 0;
         mUnlockDisabledDueToSimState = false;
         mStatus = getStatusForIccState(simState);
+        mSimState = simState;
         switch (mStatus) {
             case Normal:
-                carrierText = LockPatternUtils.getCarrierString(mUpdateMonitor.getTelephonyPlmn(),
-                        mUpdateMonitor.getTelephonySpn());
+                carrierText = makeCarierString(mPlmn, mSpn);
                 break;
 
             case NetworkLocked:
-                carrierText = LockPatternUtils.getCarrierString(mUpdateMonitor.getTelephonyPlmn(),
+                carrierText = makeCarierString(mPlmn,
                         getContext().getText(R.string.lockscreen_network_locked_message));
                 carrierHelpTextId = R.string.lockscreen_instructions_when_pattern_disabled;
                 break;
@@ -467,19 +480,19 @@
                 break;
 
             case SimMissingLocked:
-                carrierText = LockPatternUtils.getCarrierString(mUpdateMonitor.getTelephonyPlmn(),
+                carrierText = makeCarierString(mPlmn,
                         getContext().getText(R.string.lockscreen_missing_sim_message_short));
                 carrierHelpTextId = R.string.lockscreen_missing_sim_instructions;
                 mUnlockDisabledDueToSimState = true;
                 break;
 
             case SimLocked:
-                carrierText = LockPatternUtils.getCarrierString(mUpdateMonitor.getTelephonyPlmn(),
+                carrierText = makeCarierString(mPlmn,
                         getContext().getText(R.string.lockscreen_sim_locked_message));
                 break;
 
             case SimPukLocked:
-                carrierText = LockPatternUtils.getCarrierString(mUpdateMonitor.getTelephonyPlmn(),
+                carrierText = makeCarierString(mPlmn,
                         getContext().getText(R.string.lockscreen_sim_puk_locked_message));
                 if (!mLockPatternUtils.isPukUnlockScreenEnable()) {
                     mUnlockDisabledDueToSimState = true;
@@ -489,7 +502,6 @@
 
         setCarrierText(carrierText);
         setCarrierHelpText(carrierHelpTextId);
-        updateEmergencyCallButtonState();
     }
 
     private View findViewById(int id) {
@@ -552,10 +564,11 @@
         }
     }
 
-    private void updateEmergencyCallButtonState() {
+    private void updateEmergencyCallButtonState(int phoneState) {
         if (mEmergencyCallButton != null) {
             boolean showIfCapable = mShowEmergencyButtonByDefault || mUnlockDisabledDueToSimState;
-            mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton, showIfCapable);
+            mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton,
+                    phoneState, showIfCapable);
         }
     }
 
@@ -567,7 +580,8 @@
             mShowingBatteryInfo = showBatteryInfo;
             mPluggedIn = pluggedIn;
             mBatteryLevel = batteryLevel;
-            updateStatusLines(true);
+            final MutableInt tmpIcon = new MutableInt(0);
+            update(BATTERY_INFO, getAltTextMessage(tmpIcon));
         }
 
         public void onTimeChanged() {
@@ -575,15 +589,17 @@
         }
 
         public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
-            setCarrierText(LockPatternUtils.getCarrierString(plmn, spn));
+            mPlmn = plmn;
+            mSpn = spn;
+            updateCarrierTextWithSimStatus(mSimState);
         }
 
         public void onRingerModeChanged(int state) {
 
         }
 
-        public void onPhoneStateChanged(String newState) {
-            updateEmergencyCallButtonState();
+        public void onPhoneStateChanged(int phoneState) {
+            updateEmergencyCallButtonState(phoneState);
         }
 
         /** {@inheritDoc} */
@@ -595,7 +611,7 @@
     private SimStateCallback mSimStateCallback = new SimStateCallback() {
 
         public void onSimStateChanged(State simState) {
-            updateWithSimStatus(simState);
+            updateCarrierTextWithSimStatus(simState);
         }
     };
 
@@ -604,4 +620,22 @@
             mCallback.takeEmergencyCallAction();
         }
     }
+
+    /**
+     * Performs concentenation of PLMN/SPN
+     * @param plmn
+     * @param spn
+     * @return
+     */
+    private static CharSequence makeCarierString(CharSequence plmn, CharSequence spn) {
+        if (plmn != null && spn == null) {
+            return plmn;
+        } else if (plmn != null && spn != null) {
+            return plmn + "|" + spn;
+        } else if (plmn == null && spn != null) {
+            return spn;
+        } else {
+            return "";
+        }
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 2a23709..ec24f97 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -88,6 +88,8 @@
     private ArrayList<InfoCallback> mInfoCallbacks = Lists.newArrayList();
     private ArrayList<SimStateCallback> mSimStateCallbacks = Lists.newArrayList();
     private ContentObserver mContentObserver;
+    private int mRingMode;
+    private int mPhoneState;
 
     // messages for the handler
     private static final int MSG_TIME_UPDATE = 301;
@@ -271,13 +273,21 @@
 
     protected void handlePhoneStateChanged(String newState) {
         if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
+        if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
+            mPhoneState = TelephonyManager.CALL_STATE_IDLE;
+        } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
+            mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
+        } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
+            mPhoneState = TelephonyManager.CALL_STATE_RINGING;
+        }
         for (int i = 0; i < mInfoCallbacks.size(); i++) {
-            mInfoCallbacks.get(i).onPhoneStateChanged(newState);
+            mInfoCallbacks.get(i).onPhoneStateChanged(mPhoneState);
         }
     }
 
     protected void handleRingerModeChange(int mode) {
         if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
+        mRingMode = mode;
         for (int i = 0; i < mInfoCallbacks.size(); i++) {
             mInfoCallbacks.get(i).onRingerModeChanged(mode);
         }
@@ -459,7 +469,7 @@
          * {@link TelephonyManager@EXTRA_STATE_RINGING}
          * {@link TelephonyManager#EXTRA_STATE_OFFHOOK
          */
-        void onPhoneStateChanged(String newState);
+        void onPhoneStateChanged(int phoneState);
 
         /**
          * Called when visibility of lockscreen clock changes, such as when
@@ -484,8 +494,12 @@
     public void registerInfoCallback(InfoCallback callback) {
         if (!mInfoCallbacks.contains(callback)) {
             mInfoCallbacks.add(callback);
-            // notify the register the current state right away
-            // TODO: need call other callback methods
+            // Notify listener of the current state
+            callback.onRefreshBatteryInfo(shouldShowBatteryInfo(), isPluggedIn(mBatteryStatus),
+                    mBatteryLevel);
+            callback.onTimeChanged();
+            callback.onRingerModeChanged(mRingMode);
+            callback.onPhoneStateChanged(mPhoneState);
             callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
         } else {
             if (DEBUG) Log.e(TAG, "Object tried to add another INFO callback",
@@ -500,9 +514,7 @@
     public void registerSimStateCallback(SimStateCallback callback) {
         if (!mSimStateCallbacks.contains(callback)) {
             mSimStateCallbacks.add(callback);
-            // notify the register the current sim state right away,
-            // otherwise the register won't receive any state until
-            // sim state gets changed again.
+            // Notify listener of the current state
             callback.onSimStateChanged(mSimState);
         } else {
             if (DEBUG) Log.e(TAG, "Object tried to add another SIM callback",
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 64a9677..ab81875 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -782,7 +782,7 @@
                         // Don't play lockscreen SFX if the screen went off due to
                         // timeout.
                         mSuppressNextLockSound = true;
-    
+
                         doKeyguardLocked();
                     }
                 }
@@ -793,7 +793,7 @@
                     if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)  // call ending
                             && !mScreenOn                           // screen off
                             && mExternallyEnabled) {                // not disabled by any app
-    
+
                         // note: this is a way to gracefully reenable the keyguard when the call
                         // ends and the screen is off without always reenabling the keyguard
                         // each time the screen turns off while in call (and having an occasional ugly
@@ -1297,7 +1297,7 @@
     }
 
     /** {@inheritDoc} */
-    public void onPhoneStateChanged(String newState) {
+    public void onPhoneStateChanged(int phoneState) {
         // ignored
     }