Merge "Restyle USSD AlertDialog." into lmp-mr1-dev
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index a97f5d0..eae9bfc 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -708,6 +708,9 @@
         }
     }
 
+    /**
+     * TODO: Refactor to make it easier to understand what's done in the different stages.
+     */
     private void saveVoiceMailAndForwardingNumber(
             String key, VoicemailProviderSettings newSettings) {
         if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
@@ -715,8 +718,9 @@
         mNewVMNumber = (mNewVMNumber == null) ? "" : mNewVMNumber;
         mNewFwdSettings = newSettings.getForwardingSettings();
 
-        // No fwd settings on CDMA
-        if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+        // No fwd settings on CDMA.
+        boolean isCdma = mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA;
+        if (isCdma) {
             if (DBG) log("ignoring forwarding setting since this is CDMA phone");
             mNewFwdSettings = VoicemailProviderSettings.NO_FORWARDING;
         }
@@ -732,7 +736,9 @@
         mVMChangeCompletedSuccessfully = false;
         mFwdChangesRequireRollback = false;
         mVMOrFwdSetError = 0;
-        if (!key.equals(mPreviousVMProviderKey)) {
+
+        // Don't read call forwarding settings if CDMA. Call forwarding is not supported by CDMA.
+        if (!key.equals(mPreviousVMProviderKey) && !isCdma) {
             mReadingSettingsForDefaultProvider =
                     mPreviousVMProviderKey.equals(VoicemailProviderListPreference.DEFAULT_KEY);
             if (DBG) log("Reading current forwarding settings");
@@ -813,7 +819,7 @@
             if (mReadingSettingsForDefaultProvider) {
                 VoicemailProviderSettingsUtil.save(mPhone.getContext(),
                         VoicemailProviderListPreference.DEFAULT_KEY,
-                        new VoicemailProviderSettings(this.mOldVmNumber, mForwardingReadResults));
+                        new VoicemailProviderSettings(mOldVmNumber, mForwardingReadResults));
                 mReadingSettingsForDefaultProvider = false;
             }
             saveVoiceMailAndForwardingNumberStage2();
@@ -825,8 +831,7 @@
         mExpectedChangeResultReasons = new HashSet<Integer>();
     }
 
-    // Called after we are done saving the previous forwarding settings if
-    // we needed.
+    // Called after we are done saving the previous forwarding settings if we needed.
     private void saveVoiceMailAndForwardingNumberStage2() {
         mForwardingChangeResults = null;
         mVoicemailChangeResult = null;
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index d00ff9f..3e43ba1 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -281,9 +281,12 @@
         mActiveSubInfos.clear();
         if (sil != null) {
             mActiveSubInfos.addAll(sil);
+            // If there is only 1 sim then currenTab should represent slot no. of the sim.
+            if (sil.size() == 1) {
+                currentTab = sil.get(0).getSimSlotIndex();
+            }
         }
 
-
         switch (state) {
             case UPDATE: {
                 if (DBG) log("initializeSubscriptions: UPDATE");
@@ -323,7 +326,6 @@
             }
             case NO_TABS: {
                 if (DBG) log("initializeSubscriptions: NO_TABS");
-                currentTab = 0;
 
                 if (mTabHost != null) {
                     mTabHost.clearAllTabs();
@@ -334,7 +336,9 @@
             }
             case DO_NOTHING: {
                 if (DBG) log("initializeSubscriptions: DO_NOTHING");
-                currentTab = mTabHost != null ? mTabHost.getCurrentTab() : 0;
+                if (mTabHost != null) {
+                    currentTab = mTabHost.getCurrentTab();
+                }
                 break;
             }
         }
@@ -690,6 +694,9 @@
         mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
         UpdatePreferredNetworkModeSummary(settingsNetworkMode);
         UpdateEnabledNetworksValueAndSummary(settingsNetworkMode);
+        // Display preferred network type based on what modem returns b/18676277
+        mPhone.setPreferredNetworkType(settingsNetworkMode, mHandler
+                .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
 
         /**
          * Enable/disable depending upon if there are any active subscriptions.
diff --git a/src/com/android/phone/NetworkQueryService.java b/src/com/android/phone/NetworkQueryService.java
index 77f3720..b38b110 100644
--- a/src/com/android/phone/NetworkQueryService.java
+++ b/src/com/android/phone/NetworkQueryService.java
@@ -17,6 +17,7 @@
 package com.android.phone;
 
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import com.android.internal.telephony.OperatorInfo;
 import android.os.AsyncResult;
@@ -26,6 +27,7 @@
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.telephony.SubscriptionManager;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import android.util.Log;
@@ -163,8 +165,9 @@
 
     @Override
     public void onCreate() {
-        mState = QUERY_READY;
-        mPhone = PhoneFactory.getDefaultPhone();
+        mState = QUERY_READY;        
+        mPhone = PhoneFactory.getPhone(
+                SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubId()));
     }
 
     /**
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 88a13bd..c38be71 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -590,32 +590,38 @@
      */
     void updateNetworkSelection(int serviceState) {
         if (TelephonyCapabilities.supportsNetworkSelection(mPhone)) {
-            // get the shared preference of network_selection.
-            // empty is auto mode, otherwise it is the operator alpha name
-            // in case there is no operator name, check the operator numeric
-            SharedPreferences sp =
-                    PreferenceManager.getDefaultSharedPreferences(mContext);
-            String networkSelection =
-                    sp.getString(PhoneBase.NETWORK_SELECTION_NAME_KEY, "");
-            if (TextUtils.isEmpty(networkSelection)) {
-                networkSelection =
-                        sp.getString(PhoneBase.NETWORK_SELECTION_KEY, "");
-            }
+            int subId = mPhone.getSubId();
+            if (SubscriptionManager.isValidSubscriptionId(subId)) {
+                // get the shared preference of network_selection.
+                // empty is auto mode, otherwise it is the operator alpha name
+                // in case there is no operator name, check the operator numeric
+                SharedPreferences sp =
+                        PreferenceManager.getDefaultSharedPreferences(mContext);
+                String networkSelection =
+                        sp.getString(PhoneBase.NETWORK_SELECTION_NAME_KEY + subId, "");
+                if (TextUtils.isEmpty(networkSelection)) {
+                    networkSelection =
+                            sp.getString(PhoneBase.NETWORK_SELECTION_KEY + subId, "");
+                }
 
-            if (DBG) log("updateNetworkSelection()..." + "state = " +
-                    serviceState + " new network " + networkSelection);
+                if (DBG) log("updateNetworkSelection()..." + "state = " +
+                        serviceState + " new network " + networkSelection);
 
-            if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
-                    && !TextUtils.isEmpty(networkSelection)) {
-                if (!mSelectedUnavailableNotify) {
-                    showNetworkSelection(networkSelection);
-                    mSelectedUnavailableNotify = true;
+                if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
+                        && !TextUtils.isEmpty(networkSelection)) {
+                    if (!mSelectedUnavailableNotify) {
+                        showNetworkSelection(networkSelection);
+                        mSelectedUnavailableNotify = true;
+                    }
+                } else {
+                    if (mSelectedUnavailableNotify) {
+                        cancelNetworkSelection();
+                        mSelectedUnavailableNotify = false;
+                    }
                 }
             } else {
-                if (mSelectedUnavailableNotify) {
-                    cancelNetworkSelection();
-                    mSelectedUnavailableNotify = false;
-                }
+                if (DBG) log("updateNetworkSelection()..." + "state = " +
+                        serviceState + " not updating network due to invalid subId " + subId);
             }
         }
     }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 24abf23..9eb0b0b 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -209,13 +209,14 @@
             MainThreadRequest request;
             Message onCompleted;
             AsyncResult ar;
-            UiccCard uiccCard = UiccController.getInstance().getUiccCard();
+            UiccCard uiccCard = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
             IccAPDUArgument iccArgument;
 
             switch (msg.what) {
                 case CMD_HANDLE_PIN_MMI:
                     request = (MainThreadRequest) msg.obj;
-                    request.result = mPhone.handlePinMmi((String) request.argument);
+                    request.result = getPhoneFromRequest(request).handlePinMmi(
+                            (String) request.argument);
                     // Wake up the requesting thread
                     synchronized (request) {
                         request.notifyAll();
@@ -246,13 +247,13 @@
 
                 case CMD_ANSWER_RINGING_CALL:
                     request = (MainThreadRequest) msg.obj;
-                    int answer_subId = ((Integer)request.argument).intValue();
+                    int answer_subId = request.subId;
                     answerRingingCallInternal(answer_subId);
                     break;
 
                 case CMD_END_CALL:
                     request = (MainThreadRequest) msg.obj;
-                    int end_subId = ((Integer)request.argument).intValue();
+                    int end_subId = request.subId;
                     final boolean hungUp;
                     int phoneType = getPhone(end_subId).getPhoneType();
                     if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
@@ -606,8 +607,8 @@
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
                     Pair<String, String> tagNum = (Pair<String, String>) request.argument;
-                    Phone phone = (request.subId == null) ? mPhone : getPhone(request.subId);
-                    phone.setVoiceMailNumber(tagNum.first, tagNum.second, onCompleted);
+                    getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
+                            onCompleted);
                     break;
 
                 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
@@ -730,6 +731,10 @@
         ServiceManager.addService("phone", this);
     }
 
+    private Phone getPhoneFromRequest(MainThreadRequest request) {
+        return (request.subId == null) ? mPhone : getPhone(request.subId);
+    }
+
     // returns phone associated with the subId.
     private Phone getPhone(int subId) {
         return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
@@ -818,7 +823,7 @@
      */
     public boolean endCallForSubscriber(int subId) {
         enforceCallPermission();
-        return (Boolean) sendRequest(CMD_END_CALL, new Integer(subId), null);
+        return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId));
     }
 
     public void answerRingingCall() {
@@ -831,7 +836,7 @@
         // but that can probably wait till the big TelephonyManager API overhaul.
         // For now, protect this call with the MODIFY_PHONE_STATE permission.
         enforceModifyPermission();
-        sendRequest(CMD_ANSWER_RINGING_CALL, new Integer(subId), null);
+        sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId));
     }
 
     /**
@@ -1975,7 +1980,7 @@
 
     @Override
     public int getCarrierPrivilegeStatus() {
-        UiccCard card = UiccController.getInstance().getUiccCard();
+        UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
         if (card == null) {
             loge("getCarrierPrivilegeStatus: No UICC");
             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
@@ -1986,7 +1991,7 @@
 
     @Override
     public int checkCarrierPrivilegesForPackage(String pkgname) {
-        UiccCard card = UiccController.getInstance().getUiccCard();
+        UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
         if (card == null) {
             loge("checkCarrierPrivilegesForPackage: No UICC");
             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
@@ -1996,7 +2001,7 @@
 
     @Override
     public List<String> getCarrierPackageNamesForIntent(Intent intent) {
-        UiccCard card = UiccController.getInstance().getUiccCard();
+        UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
         if (card == null) {
             loge("getCarrierPackageNamesForIntent: No UICC");
             return null ;
@@ -2229,6 +2234,24 @@
                 && mTelephonySharedPreferences.getBoolean(PREF_ENABLE_VIDEO_CALLING, true);
     }
 
+    /**
+     * Returns the unique device ID of phone, for example, the IMEI for
+     * GSM and the MEID for CDMA phones. Return null if device ID is not available.
+     *
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     */
+    @Override
+    public String getDeviceId() {
+        enforceReadPermission();
+        final Phone phone = PhoneFactory.getPhone(0);
+        if (phone != null) {
+            return phone.getDeviceId();
+        } else {
+            return null;
+        }
+    }
+
     /*
      * {@hide}
      * Returns the IMS Registration Status
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 5a15a47..e692a30 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -177,6 +177,11 @@
             TelephonyConnection conferenceHost) {
 
         super(null);
+
+        // Specify the connection time of the conference to be the connection time of the original
+        // connection.
+        setConnectTimeMillis(conferenceHost.getOriginalConnection().getConnectTime());
+
         mTelephonyConnectionService = telephonyConnectionService;
         setConferenceHost(conferenceHost);
         if (conferenceHost != null && conferenceHost.getCall() != null
diff --git a/src/com/android/services/telephony/TelephonyGlobals.java b/src/com/android/services/telephony/TelephonyGlobals.java
index 11c3c64..02ef639 100644
--- a/src/com/android/services/telephony/TelephonyGlobals.java
+++ b/src/com/android/services/telephony/TelephonyGlobals.java
@@ -21,6 +21,9 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Singleton entry point for the telephony-services app. Initializes ongoing systems relating to
  * PSTN calls. This is started when the device starts and will be restarted automatically
@@ -36,7 +39,8 @@
     /** The application context. */
     private final Context mContext;
 
-    private TtyManager mTtyManager;
+    // For supporting MSIM phone, change Phone and TtyManager as 1 to 1
+    private List<TtyManager> mTtyManagers = new ArrayList<>();
 
     /**
      * Persists the specified parameters.
@@ -55,10 +59,10 @@
     }
 
     public void onCreate() {
-        // TODO: Make this work with Multi-SIM devices
-        Phone phone = PhoneFactory.getDefaultPhone();
-        if (phone != null) {
-            mTtyManager = new TtyManager(mContext, phone);
+        // Make this work with Multi-SIM devices
+        Phone[] phones = PhoneFactory.getPhones();
+        for (Phone phone : phones) {
+            mTtyManagers.add(new TtyManager(mContext, phone));
         }
 
         TelecomAccountRegistry.getInstance(mContext).setupOnBoot();
diff --git a/src/com/android/services/telephony/TtyManager.java b/src/com/android/services/telephony/TtyManager.java
index 6c8a495..a3aeeb2 100644
--- a/src/com/android/services/telephony/TtyManager.java
+++ b/src/com/android/services/telephony/TtyManager.java
@@ -122,13 +122,12 @@
 
     private static int telecomModeToPhoneMode(int telecomMode) {
         switch (telecomMode) {
+            // AT command only has 0 and 1, so mapping VCO
+            // and HCO to FULL
             case TelecomManager.TTY_MODE_FULL:
-                return Phone.TTY_MODE_FULL;
             case TelecomManager.TTY_MODE_VCO:
-                return Phone.TTY_MODE_VCO;
             case TelecomManager.TTY_MODE_HCO:
-                return Phone.TTY_MODE_HCO;
-            case TelecomManager.TTY_MODE_OFF:
+                return Phone.TTY_MODE_FULL;
             default:
                 return Phone.TTY_MODE_OFF;
         }