Enable MMI for multi-SIM (3/3)

+ Add Telecomm and Telephony methods for handlePinMMIForSubscriber
+ Add Select Account dialog in Dialer for MMI

Bug: 17917937
Change-Id: Iaabd0c5705cdf0d325aa7514d04935747078b28c
diff --git a/src/com/android/dialer/SpecialCharSequenceMgr.java b/src/com/android/dialer/SpecialCharSequenceMgr.java
index 8e56e45..2bf1afc 100644
--- a/src/com/android/dialer/SpecialCharSequenceMgr.java
+++ b/src/com/android/dialer/SpecialCharSequenceMgr.java
@@ -16,6 +16,7 @@
 
 package com.android.dialer;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.KeyguardManager;
 import android.app.ProgressDialog;
@@ -28,6 +29,7 @@
 import android.net.Uri;
 import android.os.Looper;
 import android.provider.Settings;
+import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.TelephonyManager;
@@ -38,7 +40,13 @@
 
 import com.android.common.io.MoreCloseables;
 import com.android.contacts.common.database.NoNullCursorAsyncQueryHandler;
+import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment;
+import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener;
+import com.android.dialer.calllog.PhoneAccountUtils;
+import com.android.incallui.InCallPresenter;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -217,11 +225,49 @@
         return false;
     }
 
-    static boolean handlePinEntry(Context context, String input) {
+    static boolean handlePinEntry(Context context, final String input) {
         if ((input.startsWith("**04") || input.startsWith("**05")) && input.endsWith("#")) {
-            TelecomManager telecomManager =
+            final TelecomManager telecomManager =
                     (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
-            return telecomManager.handleMmi(input);
+            List<PhoneAccountHandle> phoneAccountHandles =
+                    PhoneAccountUtils.getSubscriptionPhoneAccounts(context);
+            boolean hasUserSelectedDefault = hasDefaultSubscriptionAccount(
+                    telecomManager.getUserSelectedOutgoingPhoneAccount(), phoneAccountHandles);
+
+            if (phoneAccountHandles.size() == 1 || hasUserSelectedDefault) {
+                // Don't bring up the dialog for single-SIM or if the default outgoing account is
+                // a subscription account.
+                return telecomManager.handleMmi(input);
+            } else if (phoneAccountHandles.size() > 1){
+                SelectPhoneAccountListener listener = new SelectPhoneAccountListener() {
+                    @Override
+                    public void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle,
+                            boolean setDefault) {
+                        telecomManager.handleMmi(selectedAccountHandle, input);
+                        //TODO: show error dialog if result isn't valid
+                    }
+                    @Override
+                    public void onDialogDismissed() {}
+                };
+
+                SelectPhoneAccountDialogFragment.showAccountDialog(
+                        ((Activity) context).getFragmentManager(), false, phoneAccountHandles,
+                        listener);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if the default outgoing phone account set is a subscription phone account.
+     */
+    static private boolean hasDefaultSubscriptionAccount(PhoneAccountHandle defaultOutgoingAccount,
+            List<PhoneAccountHandle> phoneAccountHandles) {
+        for (PhoneAccountHandle accountHandle : phoneAccountHandles) {
+            if (accountHandle.equals(defaultOutgoingAccount)) {
+                return true;
+            }
         }
         return false;
     }
diff --git a/src/com/android/dialer/calllog/PhoneAccountUtils.java b/src/com/android/dialer/calllog/PhoneAccountUtils.java
index 20b81d8..eb9e433 100644
--- a/src/com/android/dialer/calllog/PhoneAccountUtils.java
+++ b/src/com/android/dialer/calllog/PhoneAccountUtils.java
@@ -24,12 +24,33 @@
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Methods to help extract {@code PhoneAccount} information from database and Telecomm sources
  */
 public class PhoneAccountUtils {
     /**
-     * Compose PhoneAccount object from component name and account id
+     * Return a list of phone accounts that are subscription/SIM accounts.
+     */
+    public static List<PhoneAccountHandle> getSubscriptionPhoneAccounts(Context context) {
+        final TelecomManager telecomManager =
+                (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
+
+        List<PhoneAccountHandle> subscriptionAccountHandles = new ArrayList<PhoneAccountHandle>();
+        List<PhoneAccountHandle> accountHandles = telecomManager.getCallCapablePhoneAccounts();
+        for (PhoneAccountHandle accountHandle : accountHandles) {
+            PhoneAccount account = telecomManager.getPhoneAccount(accountHandle);
+            if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
+                subscriptionAccountHandles.add(accountHandle);
+            }
+        }
+        return subscriptionAccountHandles;
+    }
+
+    /**
+     * Compose PhoneAccount object from component name and account id.
      */
     public static PhoneAccountHandle getAccount(String componentString, String accountId) {
         if (TextUtils.isEmpty(componentString) || TextUtils.isEmpty(accountId)) {
@@ -40,7 +61,7 @@
     }
 
     /**
-     * Extract account icon from PhoneAccount object
+     * Extract account icon from PhoneAccount object.
      */
     public static Drawable getAccountIcon(Context context, PhoneAccountHandle phoneAccount) {
         final PhoneAccount account = getAccountOrNull(context, phoneAccount);
@@ -51,7 +72,7 @@
     }
 
     /**
-     * Extract account label from PhoneAccount object
+     * Extract account label from PhoneAccount object.
      */
     public static String getAccountLabel(Context context, PhoneAccountHandle phoneAccount) {
         final PhoneAccount account = getAccountOrNull(context, phoneAccount);
@@ -74,5 +95,4 @@
         }
         return account;
     }
-
 }