Merge "Add SIM Depersonalisation interface"
diff --git a/res/layout/sim_ndp.xml b/res/layout/sim_ndp.xml
index 5e3c472..5f03d7b 100644
--- a/res/layout/sim_ndp.xml
+++ b/res/layout/sim_ndp.xml
@@ -29,6 +29,7 @@
             android:layout_centerInParent="true">
 
         <TextView
+                android:id="@+id/perso_subtype_text"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
diff --git a/src/com/android/phone/IccNetworkDepersonalizationPanel.java b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
index 8bd10a2..7d854cd 100644
--- a/src/com/android/phone/IccNetworkDepersonalizationPanel.java
+++ b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
@@ -22,7 +22,10 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.telephony.CarrierConfigManager;
+import android.telephony.TelephonyManager;
 import android.text.Editable;
 import android.text.Spannable;
 import android.text.TextUtils;
@@ -37,6 +40,8 @@
 import android.widget.TextView;
 
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
 
 /**
  * "SIM network unlock" PIN entry screen.
@@ -52,7 +57,8 @@
      * Tracks whether there is an instance of the network depersonalization dialog showing or not.
      * Ensures only a single instance of the dialog is visible.
      */
-    private static boolean sShowingDialog = false;
+    private static boolean [] sShowingDialog =
+            new boolean[TelephonyManager.getDefault().getSimCount()];
 
     //debug constants
     private static final boolean DBG = false;
@@ -61,29 +67,48 @@
     private static final int EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT = 100;
 
     private Phone mPhone;
+    private int mPersoSubtype;
+    private static IccNetworkDepersonalizationPanel [] sNdpPanel =
+            new IccNetworkDepersonalizationPanel[TelephonyManager.getDefault().getSimCount()];
 
     //UI elements
     private EditText     mPinEntry;
     private LinearLayout mEntryPanel;
     private LinearLayout mStatusPanel;
+    private TextView     mPersoSubtypeText;
+    private PersoSubState mPersoSubState;
     private TextView     mStatusText;
 
     private Button       mUnlockButton;
     private Button       mDismissButton;
 
+    enum statusType {
+        ENTRY,
+        IN_PROGRESS,
+        ERROR,
+        SUCCESS
+    }
+
     /**
      * Shows the network depersonalization dialog, but only if it is not already visible.
      */
-    public static void showDialog(Phone phone) {
-        if (sShowingDialog) {
+    public static void showDialog(Phone phone, int subType) {
+        int phoneId = phone == null ? 0: phone.getPhoneId();
+        if (sShowingDialog[phoneId]) {
             Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; skipped already shown.");
             return;
         }
         Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; showing dialog.");
-        sShowingDialog = true;
-        IccNetworkDepersonalizationPanel ndpPanel =
-                new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance(), phone);
-        ndpPanel.show();
+        sShowingDialog[phoneId] = true;
+        sNdpPanel[phoneId] = new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance(),
+                phone, subType);
+        sNdpPanel[phoneId].show();
+    }
+
+    public static void dialogDismiss(int phoneId) {
+        if (sNdpPanel[phoneId] != null && sShowingDialog[phoneId]) {
+            sNdpPanel[phoneId].dismiss();
+        }
     }
 
     //private textwatcher to control text entry.
@@ -109,37 +134,41 @@
                 AsyncResult res = (AsyncResult) msg.obj;
                 if (res.exception != null) {
                     if (DBG) log("network depersonalization request failure.");
-                    indicateError();
+                    displayStatus(statusType.ERROR.name());
                     postDelayed(new Runnable() {
-                                    public void run() {
-                                        hideAlert();
-                                        mPinEntry.getText().clear();
-                                        mPinEntry.requestFocus();
-                                    }
-                                }, 3000);
+                        public void run() {
+                            hideAlert();
+                            mPinEntry.getText().clear();
+                            mPinEntry.requestFocus();
+                        }
+                    }, 3000);
                 } else {
                     if (DBG) log("network depersonalization success.");
-                    indicateSuccess();
+                    displayStatus(statusType.SUCCESS.name());
                     postDelayed(new Runnable() {
-                                    public void run() {
-                                        dismiss();
-                                    }
-                                }, 3000);
+                        public void run() {
+                            dismiss();
+                        }
+                    }, 3000);
                 }
             }
         }
     };
 
+
     //constructor
     public IccNetworkDepersonalizationPanel(Context context) {
         super(context);
         mPhone = PhoneGlobals.getPhone();
+        mPersoSubtype = PersoSubState.PERSOSUBSTATE_SIM_NETWORK.ordinal();
     }
 
     //constructor
-    public IccNetworkDepersonalizationPanel(Context context, Phone phone) {
+    public IccNetworkDepersonalizationPanel(Context context, Phone phone,
+            int subtype) {
         super(context);
         mPhone = phone == null ? PhoneGlobals.getPhone() : phone;
+        mPersoSubtype = subtype;
     }
 
     @Override
@@ -158,6 +187,8 @@
         span.setSpan(mPinEntryWatcher, 0, text.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
 
         mEntryPanel = (LinearLayout) findViewById(R.id.entry_panel);
+        mPersoSubtypeText = (TextView) findViewById(R.id.perso_subtype_text);
+        displayStatus(statusType.ENTRY.name());
 
         mUnlockButton = (Button) findViewById(R.id.ndp_unlock);
         mUnlockButton.setOnClickListener(mUnlockListener);
@@ -190,7 +221,8 @@
     public void onStop() {
         super.onStop();
         Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; hiding dialog.");
-        sShowingDialog = false;
+        int phoneId = mPhone == null ? 0 : mPhone.getPhoneId();
+        sShowingDialog[phoneId] = false;
     }
 
     //Mirrors IccPinUnlockPanel.onKeyDown().
@@ -210,29 +242,45 @@
                 return;
             }
 
-            if (DBG) log("requesting network depersonalization with code " + pin);
-            mPhone.getIccCard().supplyNetworkDepersonalization(pin,
-                    Message.obtain(mHandler, EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT));
-            indicateBusy();
+            log("Requesting De-Personalization for subtype " + mPersoSubtype);
+
+            try {
+                mPhone.getIccCard().supplySimDepersonalization(mPersoSubState,pin,
+                        Message.obtain(mHandler, EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT));
+            } catch (NullPointerException ex) {
+                log("NullPointerException @supplySimDepersonalization" + ex);
+            }
+            displayStatus(statusType.IN_PROGRESS.name());
         }
     };
 
-    private void indicateBusy() {
-        mStatusText.setText(R.string.requesting_unlock);
-        mEntryPanel.setVisibility(View.GONE);
-        mStatusPanel.setVisibility(View.VISIBLE);
-    }
+    private void displayStatus(String type) {
+        int label = 0;
 
-    private void indicateError() {
-        mStatusText.setText(R.string.unlock_failed);
-        mEntryPanel.setVisibility(View.GONE);
-        mStatusPanel.setVisibility(View.VISIBLE);
-    }
+        mPersoSubState = PersoSubState.values()[mPersoSubtype];
+        log("displayStatus mPersoSubState: " +mPersoSubState.name() +"type: " +type);
 
-    private void indicateSuccess() {
-        mStatusText.setText(R.string.unlock_success);
-        mEntryPanel.setVisibility(View.GONE);
-        mStatusPanel.setVisibility(View.VISIBLE);
+        label = getContext().getResources().getIdentifier(mPersoSubState.name()
+                + "_" + type, "string", "android");
+
+        if (label == 0) {
+            log ("Unable to get the PersoSubType string");
+            return;
+        }
+
+        if(!PersoSubState.isPersoLocked(mPersoSubState)) {
+            log ("Unsupported Perso Subtype :" + mPersoSubState.name());
+            return;
+        }
+
+        if (type == statusType.ENTRY.name()) {
+            String displayText = getContext().getString(label);
+            mPersoSubtypeText.setText(displayText);
+        } else {
+            mStatusText.setText(label);
+            mEntryPanel.setVisibility(View.GONE);
+            mStatusPanel.setVisibility(View.VISIBLE);
+        }
     }
 
     private void hideAlert() {
@@ -241,13 +289,13 @@
     }
 
     View.OnClickListener mDismissListener = new View.OnClickListener() {
-            public void onClick(View v) {
-                if (DBG) log("mDismissListener: skipping depersonalization...");
-                dismiss();
-            }
-        };
+        public void onClick(View v) {
+            if (DBG) log("mDismissListener: skipping depersonalization...");
+            dismiss();
+        }
+    };
 
     private void log(String msg) {
-        Log.v(TAG, "[IccNetworkDepersonalizationPanel] " + msg);
+        Log.d(TAG, "[IccNetworkDepersonalizationPanel] " + msg);
     }
 }
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 6f657b4..df1f470 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -205,6 +205,16 @@
 
     private final SettingsObserver mSettingsObserver;
 
+    private static class EventSimStateChangedBag {
+        final int mPhoneId;
+        final String mIccStatus;
+
+        EventSimStateChangedBag(int phoneId, String iccStatus) {
+            mPhoneId = phoneId;
+            mIccStatus = iccStatus;
+        }
+    }
+
     Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -225,7 +235,8 @@
                         // they enter a valid SIM network PIN.
                         Log.i(LOG_TAG, "show sim depersonal panel");
                         Phone phone = (Phone) ((AsyncResult) msg.obj).userObj;
-                        IccNetworkDepersonalizationPanel.showDialog(phone);
+                        int subType = (Integer)((AsyncResult)msg.obj).result;
+                        IccNetworkDepersonalizationPanel.showDialog(phone, subType);
                     }
                     break;
 
@@ -253,8 +264,9 @@
                     // Marks the event where the SIM goes into ready state.
                     // Right now, this is only used for the PUK-unlocking
                     // process.
-                    if (msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_READY)
-                            || msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_LOADED)) {
+                    EventSimStateChangedBag bag = (EventSimStateChangedBag)msg.obj;
+                    if (bag.mIccStatus == IccCardConstants.INTENT_VALUE_ICC_READY
+                            || bag.mIccStatus == IccCardConstants.INTENT_VALUE_ICC_LOADED) {
                         // when the right event is triggered and there
                         // are UI objects in the foreground, we close
                         // them to display the lock panel.
@@ -266,6 +278,8 @@
                             mPUKEntryProgressDialog.dismiss();
                             mPUKEntryProgressDialog = null;
                         }
+                        Log.i(LOG_TAG, "Dismissing depersonal panel");
+                        IccNetworkDepersonalizationPanel.dialogDismiss(bag.mPhoneId);
                     }
                     break;
 
@@ -649,14 +663,9 @@
                     PhoneUtils.unregisterIccStatus(mHandler, phoneId);
                     PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED, phoneId);
                 }
-                if (mPUKEntryActivity != null) {
-                    // if an attempt to un-PUK-lock the device was made, while we're
-                    // receiving this state change notification, notify the handler.
-                    // NOTE: This is ONLY triggered if an attempt to un-PUK-lock has
-                    // been attempted.
-                    mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
-                            intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)));
-                }
+                String iccStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
+                        new EventSimStateChangedBag(phoneId, iccStatus)));
             } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
                 String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
                 Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");