Add multi-sim support to keyguard

Use new telephony APIs.
Clean up SIM state machine code.
Use cached copy of SubscriptionInfo.
Make SIM PIN and SIM PUK work.

Tested on single and multi-SIM devices.

Fixes bug 18147652

Change-Id: Ic69a4d2898999a5438e6a70b5851705bc05443f1
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index f0c5805..c5d940c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -17,18 +17,24 @@
 package com.android.keyguard;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.ProgressDialog;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.WindowManager;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.IccCardConstants.State;
 
 
 /**
@@ -45,6 +51,23 @@
     private String mPinText;
     private StateMachine mStateMachine = new StateMachine();
     private AlertDialog mRemainingAttemptsDialog;
+    private int mSubId;
+
+    KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onSimStateChanged(int subId, int slotId, State simState) {
+           if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")");
+           resetState();
+       };
+    };
+
+    public KeyguardSimPukView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardSimPukView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
 
     private class StateMachine {
         final int ENTER_PUK = 0;
@@ -89,7 +112,21 @@
             mPinText="";
             mPukText="";
             state = ENTER_PUK;
-            mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
+            KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+            mSubId = monitor.getNextSubIdForState(IccCardConstants.State.PUK_REQUIRED);
+            if (mSubId != SubscriptionManager.INVALID_SUB_ID) {
+                int count = TelephonyManager.getDefault().getSimCount();
+                Resources rez = getResources();
+                final String msg;
+                if (count < 2) {
+                    msg = rez.getString(R.string.kg_puk_enter_puk_hint);
+                } else {
+                    SubscriptionInfo info = monitor.getSubscriptionInfoForSubId(mSubId);
+                    CharSequence displayName = info != null ? info.getDisplayName() : "";
+                    msg = rez.getString(R.string.kg_puk_enter_puk_hint_multi, displayName);
+                }
+                mSecurityMessageDisplay.setMessage(msg, true);
+            }
             mPasswordEntry.requestFocus();
         }
     }
@@ -111,14 +148,6 @@
         return displayMessage;
     }
 
-    public KeyguardSimPukView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardSimPukView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
     public void resetState() {
         super.resetState();
         mStateMachine.reset();
@@ -146,6 +175,18 @@
     }
 
     @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallback);
+    }
+
+    @Override
     public void showUsabilityHint() {
     }
 
@@ -165,10 +206,12 @@
     private abstract class CheckSimPuk extends Thread {
 
         private final String mPin, mPuk;
+        private final int mSubId;
 
-        protected CheckSimPuk(String puk, String pin) {
+        protected CheckSimPuk(String puk, String pin, int subId) {
             mPuk = puk;
             mPin = pin;
+            mSubId = subId;
         }
 
         abstract void onSimLockChangedResponse(final int result, final int attemptsRemaining);
@@ -176,10 +219,12 @@
         @Override
         public void run() {
             try {
-                Log.v(TAG, "call supplyPukReportResult()");
+                if (DEBUG) Log.v(TAG, "call supplyPukReportResult()");
                 final int[] result = ITelephony.Stub.asInterface(ServiceManager
-                        .checkService("phone")).supplyPukReportResult(mPuk, mPin);
-                Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]);
+                    .checkService("phone")).supplyPukReportResultForSubscriber(mSubId, mPuk, mPin);
+                if (DEBUG) {
+                    Log.v(TAG, "supplyPukReportResult returned: " + result[0] + " " + result[1]);
+                }
                 post(new Runnable() {
                     public void run() {
                         onSimLockChangedResponse(result[0], result[1]);
@@ -254,15 +299,17 @@
         getSimUnlockProgressDialog().show();
 
         if (mCheckSimPukThread == null) {
-            mCheckSimPukThread = new CheckSimPuk(mPukText, mPinText) {
+            mCheckSimPukThread = new CheckSimPuk(mPukText, mPinText, mSubId) {
                 void onSimLockChangedResponse(final int result, final int attemptsRemaining) {
                     post(new Runnable() {
                         public void run() {
                             if (mSimUnlockProgressDialog != null) {
                                 mSimUnlockProgressDialog.hide();
                             }
+                            resetPasswordText(true /* animate */);
                             if (result == PhoneConstants.PIN_RESULT_SUCCESS) {
-                                KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
+                                KeyguardUpdateMonitor.getInstance(getContext())
+                                        .reportSimUnlocked(mSubId);
                                 mCallback.dismiss(true);
                             } else {
                                 if (result == PhoneConstants.PIN_PASSWORD_INCORRECT) {