Display remaining attempts when using or changing SIM PIN

Bug: 9928717
Change-Id: I73718c9e6a8aa7244097e0dd4593a6226ff0ac08
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e6b8864..2648fff 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1948,6 +1948,19 @@
     <!-- SIM card lock settings screen, SIM PIN dialog button labels: -->
     <string name="sim_enter_cancel">Cancel</string>
 
+    <!-- Instructions telling the user that they entered the wrong SIM PIN for the last time.
+         Displayed in a dialog box.  -->
+    <string name="wrong_pin_code_pukked">Incorrect SIM PIN code you must now contact your carrier to unlock your device.</string>
+    <!-- Instructions telling the user that they entered the wrong SIM PIN while trying
+         to unlock the keyguard.  Displayed in a dialog box.  -->
+    <plurals name="wrong_pin_code">
+        <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before you must contact your carrier to unlock your device.</item>
+        <item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempts.</item>
+    </plurals>
+    <!-- Instructions telling the user that the operation to unlock the keyguard
+         with SIM PIN failed. Displayed in one line in a large font.  -->
+    <string name="pin_failed">SIM PIN operation failed!</string>
+
     <!-- Advanced (used for diagnostics) device info activity title -->
     <string name="device_info_settings" product="tablet">Tablet status</string>
     <!-- Advanced (used for diagnostics) device info activity title -->
diff --git a/src/com/android/settings/IccLockSettings.java b/src/com/android/settings/IccLockSettings.java
index ab12587..b988572 100644
--- a/src/com/android/settings/IccLockSettings.java
+++ b/src/com/android/settings/IccLockSettings.java
@@ -29,6 +29,7 @@
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
+import android.util.Log;
 import android.widget.Toast;
 
 import com.android.internal.telephony.Phone;
@@ -46,6 +47,8 @@
  */
 public class IccLockSettings extends PreferenceActivity
         implements EditPinPreference.OnPinEnteredListener {
+    private static final String TAG = "IccLockSettings";
+    private static final boolean DBG = true;
 
     private static final int OFF_MODE = 0;
     // State when enabling/disabling ICC lock
@@ -101,10 +104,10 @@
             AsyncResult ar = (AsyncResult) msg.obj;
             switch (msg.what) {
                 case MSG_ENABLE_ICC_PIN_COMPLETE:
-                    iccLockChanged(ar.exception == null);
+                    iccLockChanged(ar.exception == null, msg.arg1);
                     break;
                 case MSG_CHANGE_ICC_PIN_COMPLETE:
-                    iccPinChanged(ar.exception == null);
+                    iccPinChanged(ar.exception == null, msg.arg1);
                     break;
                 case MSG_SIM_STATE_CHANGED:
                     updatePreferences();
@@ -352,21 +355,21 @@
         mPinToggle.setEnabled(false);
     }
 
-    private void iccLockChanged(boolean success) {
+    private void iccLockChanged(boolean success, int attemptsRemaining) {
         if (success) {
             mPinToggle.setChecked(mToState);
         } else {
-            Toast.makeText(this, mRes.getString(R.string.sim_lock_failed), Toast.LENGTH_SHORT)
+            Toast.makeText(this, getPinPasswordErrorMessage(attemptsRemaining), Toast.LENGTH_LONG)
                     .show();
         }
         mPinToggle.setEnabled(true);
         resetDialogState();
     }
 
-    private void iccPinChanged(boolean success) {
+    private void iccPinChanged(boolean success, int attemptsRemaining) {
         if (!success) {
-            Toast.makeText(this, mRes.getString(R.string.sim_change_failed),
-                    Toast.LENGTH_SHORT)
+            Toast.makeText(this, getPinPasswordErrorMessage(attemptsRemaining),
+                    Toast.LENGTH_LONG)
                     .show();
         } else {
             Toast.makeText(this, mRes.getString(R.string.sim_change_succeeded),
@@ -383,6 +386,23 @@
                 mNewPin, callback);
     }
 
+    private String getPinPasswordErrorMessage(int attemptsRemaining) {
+        String displayMessage;
+
+        if (attemptsRemaining == 0) {
+            displayMessage = mRes.getString(R.string.wrong_pin_code_pukked);
+        } else if (attemptsRemaining > 0) {
+            displayMessage = mRes
+                    .getQuantityString(R.plurals.wrong_pin_code, attemptsRemaining,
+                            attemptsRemaining);
+        } else {
+            displayMessage = mRes.getString(R.string.pin_failed);
+        }
+        if (DBG) Log.d(TAG, "getPinPasswordErrorMessage:"
+                + " attemptsRemaining=" + attemptsRemaining + " displayMessage=" + displayMessage);
+        return displayMessage;
+    }
+
     private boolean reasonablePin(String pin) {
         if (pin == null || pin.length() < MIN_PIN_LENGTH || pin.length() > MAX_PIN_LENGTH) {
             return false;