Merge "String resource edits for Telephony" into lmp-mr1-dev
diff --git a/res/drawable-hdpi/ic_multi_sim1.png b/res/drawable-hdpi/ic_multi_sim1.png
deleted file mode 100644
index 12b800c..0000000
--- a/res/drawable-hdpi/ic_multi_sim1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_multi_sim2.png b/res/drawable-hdpi/ic_multi_sim2.png
deleted file mode 100644
index d468081..0000000
--- a/res/drawable-hdpi/ic_multi_sim2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_multi_sim3.png b/res/drawable-hdpi/ic_multi_sim3.png
deleted file mode 100644
index be17bd4..0000000
--- a/res/drawable-hdpi/ic_multi_sim3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_multi_sim4.png b/res/drawable-hdpi/ic_multi_sim4.png
deleted file mode 100644
index fbff161..0000000
--- a/res/drawable-hdpi/ic_multi_sim4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_multi_sim1.png b/res/drawable-mdpi/ic_multi_sim1.png
deleted file mode 100644
index ef350bf..0000000
--- a/res/drawable-mdpi/ic_multi_sim1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_multi_sim2.png b/res/drawable-mdpi/ic_multi_sim2.png
deleted file mode 100644
index a265723..0000000
--- a/res/drawable-mdpi/ic_multi_sim2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_multi_sim3.png b/res/drawable-mdpi/ic_multi_sim3.png
deleted file mode 100644
index cce2d3f..0000000
--- a/res/drawable-mdpi/ic_multi_sim3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_multi_sim4.png b/res/drawable-mdpi/ic_multi_sim4.png
deleted file mode 100644
index 233c386..0000000
--- a/res/drawable-mdpi/ic_multi_sim4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_multi_sim1.png b/res/drawable-xhdpi/ic_multi_sim1.png
deleted file mode 100644
index 1ad3288..0000000
--- a/res/drawable-xhdpi/ic_multi_sim1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_multi_sim2.png b/res/drawable-xhdpi/ic_multi_sim2.png
deleted file mode 100644
index 3a4152e..0000000
--- a/res/drawable-xhdpi/ic_multi_sim2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_multi_sim3.png b/res/drawable-xhdpi/ic_multi_sim3.png
deleted file mode 100644
index 4c36a1c..0000000
--- a/res/drawable-xhdpi/ic_multi_sim3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_multi_sim4.png b/res/drawable-xhdpi/ic_multi_sim4.png
deleted file mode 100644
index 26db92c..0000000
--- a/res/drawable-xhdpi/ic_multi_sim4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_multi_sim1.png b/res/drawable-xxhdpi/ic_multi_sim1.png
deleted file mode 100644
index 6d89d58..0000000
--- a/res/drawable-xxhdpi/ic_multi_sim1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_multi_sim2.png b/res/drawable-xxhdpi/ic_multi_sim2.png
deleted file mode 100644
index b9f3351..0000000
--- a/res/drawable-xxhdpi/ic_multi_sim2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_multi_sim3.png b/res/drawable-xxhdpi/ic_multi_sim3.png
deleted file mode 100644
index beef5c8..0000000
--- a/res/drawable-xxhdpi/ic_multi_sim3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_multi_sim4.png b/res/drawable-xxhdpi/ic_multi_sim4.png
deleted file mode 100644
index b947e84..0000000
--- a/res/drawable-xxhdpi/ic_multi_sim4.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_multi_sim1.png b/res/drawable-xxxhdpi/ic_multi_sim1.png
deleted file mode 100644
index a4ebf5c..0000000
--- a/res/drawable-xxxhdpi/ic_multi_sim1.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_multi_sim2.png b/res/drawable-xxxhdpi/ic_multi_sim2.png
deleted file mode 100644
index 5835784..0000000
--- a/res/drawable-xxxhdpi/ic_multi_sim2.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_multi_sim3.png b/res/drawable-xxxhdpi/ic_multi_sim3.png
deleted file mode 100644
index cc9ef41..0000000
--- a/res/drawable-xxxhdpi/ic_multi_sim3.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_multi_sim4.png b/res/drawable-xxxhdpi/ic_multi_sim4.png
deleted file mode 100644
index 49f2c09..0000000
--- a/res/drawable-xxxhdpi/ic_multi_sim4.png
+++ /dev/null
Binary files differ
diff --git a/res/layout/network_settings.xml b/res/layout/network_settings.xml
new file mode 100644
index 0000000..d2a4acc
--- /dev/null
+++ b/res/layout/network_settings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/tabhost"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:id="@+id/tabs_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scrollbars="none"
+            android:fillViewport="true">
+
+            <TabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                style="?android:attr/tabWidgetStyle" />
+
+        </HorizontalScrollView>
+
+        <!-- give an empty content area to make tabhost happy -->
+        <FrameLayout
+            android:id="@android:id/tabcontent"
+            android:layout_width="0dip"
+            android:layout_height="0dip" />
+
+        <ListView
+            android:id="@android:id/list"
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:clipChildren="false"
+            android:clipToPadding="false"
+            android:smoothScrollbar="false" />
+
+    </LinearLayout>
+
+</TabHost>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b32553c..6476f50 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -126,7 +126,7 @@
     <string name="settings_label">Network settings</string>
 
     <!-- Label for settings screen for phone accounts. -->
-    <string name="phone_accounts">Phone account settings</string>
+    <string name="phone_accounts">Calling accounts</string>
     <!-- Label for list item which opens a dialog to select the default outgoing account -->
     <string name="phone_accounts_make_calls_with">Make calls with</string>
     <!-- Label for list item which opens a dialog to select the default outgoing account for SIP calls. -->
diff --git a/res/xml/call_feature_setting.xml b/res/xml/call_feature_setting.xml
index 0182ac0..2ad10f2 100644
--- a/res/xml/call_feature_setting.xml
+++ b/res/xml/call_feature_setting.xml
@@ -25,7 +25,7 @@
             android:targetPackage="com.android.phone"
             android:targetClass="com.android.phone.settings.PhoneAccountSettingsActivity"/>
 
-    </PreferenceScreen>>
+    </PreferenceScreen>
 
     <PreferenceScreen
         android:key="button_voicemail_category_key"
diff --git a/sip/src/com/android/services/telephony/sip/SipUtil.java b/sip/src/com/android/services/telephony/sip/SipUtil.java
index df1a03a..54bdc1e 100644
--- a/sip/src/com/android/services/telephony/sip/SipUtil.java
+++ b/sip/src/com/android/services/telephony/sip/SipUtil.java
@@ -119,9 +119,7 @@
                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
                 .setAddress(Uri.parse(profile.getUriString()))
                 .setShortDescription(profile.getDisplayName())
-                .setIconBitmap(BitmapFactory.decodeResource(
-                        context.getResources(),
-                        R.drawable.ic_dialer_sip_black_24dp))
+                .setIcon(context, R.drawable.ic_dialer_sip_black_24dp)
                 .setSupportedUriSchemes(supportedUriSchemes);
 
         return builder.build();
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 02bbf6d..2755bd7 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -21,7 +21,6 @@
 import android.app.ActivityOptions;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.ProgressDialog;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -52,7 +51,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.MenuItem;
-import android.view.WindowManager;
 import android.widget.ListAdapter;
 
 import com.android.ims.ImsManager;
@@ -62,6 +60,7 @@
 import com.android.phone.common.util.SettingsUtil;
 import com.android.phone.settings.AccountSelectionPreference;
 import com.android.phone.settings.CallForwardInfoUtil;
+import com.android.phone.settings.VoicemailDialogUtil;
 import com.android.phone.settings.VoicemailProviderSettings;
 import com.android.phone.settings.VoicemailProviderSettingsUtil;
 import com.android.phone.settings.fdn.FdnSetting;
@@ -190,18 +189,6 @@
     private AudioManager mAudioManager;
     private VoicemailProviderSettingsUtil mVmProviderSettingsUtil;
 
-    private static final int VM_NOCHANGE_ERROR = 400;
-    private static final int VM_RESPONSE_ERROR = 500;
-    private static final int FW_SET_RESPONSE_ERROR = 501;
-    private static final int FW_GET_RESPONSE_ERROR = 502;
-
-
-    // dialog identifiers for voicemail
-    private static final int VOICEMAIL_DIALOG_CONFIRM = 600;
-    private static final int VOICEMAIL_FWD_SAVING_DIALOG = 601;
-    private static final int VOICEMAIL_FWD_READING_DIALOG = 602;
-    private static final int VOICEMAIL_REVERTING_DIALOG = 603;
-
     // voicemail notification vibration string constants
     private static final String VOICEMAIL_VIBRATION_ALWAYS = "always";
     private static final String VOICEMAIL_VIBRATION_NEVER = "never";
@@ -523,7 +510,7 @@
         }
 
         if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
-            showDialogIfForeground(VOICEMAIL_REVERTING_DIALOG);
+            showDialogIfForeground(VoicemailDialogUtil.VM_REVERTING_DIALOG);
             final VoicemailProviderSettings prevSettings =
                     mVmProviderSettingsUtil.load(mPreviousVMProviderKey);
             if (prevSettings == null) {
@@ -734,7 +721,7 @@
         // Throw a warning if the voicemail is the same and we did not change forwarding.
         if (mNewVMNumber.equals(mOldVmNumber)
                 && mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING) {
-            showDialogIfForeground(VM_NOCHANGE_ERROR);
+            showDialogIfForeground(VoicemailDialogUtil.VM_NOCHANGE_ERROR_DIALOG);
             return;
         }
 
@@ -753,7 +740,7 @@
                         VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[i],
                         mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
             }
-            showDialogIfForeground(VOICEMAIL_FWD_READING_DIALOG);
+            showDialogIfForeground(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
         } else {
             saveVoiceMailAndForwardingNumberStage2();
         }
@@ -794,8 +781,8 @@
         if (error != null) {
             if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
             mForwardingReadResults = null;
-            dismissDialogSafely(VOICEMAIL_FWD_READING_DIALOG);
-            showDialogIfForeground(FW_GET_RESPONSE_ERROR);
+            dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
+            showDialogIfForeground(VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG);
             return;
         }
 
@@ -815,7 +802,7 @@
 
         if (done) {
             if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
-            dismissDialogSafely(VOICEMAIL_FWD_READING_DIALOG);
+            dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
 
             if (mReadingSettingsForDefaultProvider) {
                 mVmProviderSettingsUtil.save(DEFAULT_VM_PROVIDER_KEY,
@@ -853,7 +840,7 @@
                                     EVENT_FORWARDING_CHANGED, fi.reason, 0));
                 }
             }
-            showDialogIfForeground(VOICEMAIL_FWD_SAVING_DIALOG);
+            showDialogIfForeground(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
         } else {
             if (DBG) log("Not touching fwd #");
             setVMNumberWithCarrier();
@@ -922,7 +909,7 @@
             if (done) {
                 if (DBG) log("All VM provider related changes done");
                 if (mForwardingChangeResults != null) {
-                    dismissDialogSafely(VOICEMAIL_FWD_SAVING_DIALOG);
+                    dismissDialogSafely(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
                 }
                 handleSetVmOrFwdMessage();
             }
@@ -959,7 +946,7 @@
                     && (!mFwdChangesRequireRollback || isForwardingCompleted());
             if (done) {
                 if (DBG) log("All VM reverts done");
-                dismissDialogSafely(VOICEMAIL_REVERTING_DIALOG);
+                dismissDialogSafely(VoicemailDialogUtil.VM_REVERTING_DIALOG);
                 onRevertDone();
             }
         }
@@ -1013,11 +1000,11 @@
         if (DBG) log("handleSetVMMessage: set VM request complete");
 
         if (!isFwdChangeSuccess()) {
-            handleVmOrFwdSetError(FW_SET_RESPONSE_ERROR);
+            handleVmOrFwdSetError(VoicemailDialogUtil.FWD_SET_RESPONSE_ERROR_DIALOG);
         } else if (!isVmChangeSuccess()) {
-            handleVmOrFwdSetError(VM_RESPONSE_ERROR);
+            handleVmOrFwdSetError(VoicemailDialogUtil.VM_RESPONSE_ERROR_DIALOG);
         } else {
-            handleVmAndFwdSetSuccess(VOICEMAIL_DIALOG_CONFIRM);
+            handleVmAndFwdSetSuccess(VoicemailDialogUtil.VM_CONFIRM_DIALOG);
         }
     }
 
@@ -1026,7 +1013,7 @@
      * changes to those settings and show "failure" dialog.
      *
      * @param dialogId ID of the dialog to show for the specific error case. Either
-     *     {@link #FW_SET_RESPONSE_ERROR} or {@link #VM_RESPONSE_ERROR}
+     *     {@link #FWD_SET_RESPONSE_ERROR_DIALOG} or {@link #VM_RESPONSE_ERROR_DIALOG}
      */
     private void handleVmOrFwdSetError(int dialogId) {
         if (mChangingVMorFwdDueToProviderChange) {
@@ -1086,78 +1073,8 @@
 
     // dialog creation method, called by showDialog()
     @Override
-    protected Dialog onCreateDialog(int id) {
-        if ((id == VM_RESPONSE_ERROR) || (id == VM_NOCHANGE_ERROR) ||
-            (id == FW_SET_RESPONSE_ERROR) || (id == FW_GET_RESPONSE_ERROR) ||
-                (id == VOICEMAIL_DIALOG_CONFIRM)) {
-
-            AlertDialog.Builder b = new AlertDialog.Builder(this);
-
-            int msgId;
-            int titleId = R.string.error_updating_title;
-            switch (id) {
-                case VOICEMAIL_DIALOG_CONFIRM:
-                    msgId = R.string.vm_changed;
-                    titleId = R.string.voicemail;
-                    // Set Button 2
-                    b.setNegativeButton(R.string.close_dialog, this);
-                    break;
-                case VM_NOCHANGE_ERROR:
-                    // even though this is technically an error,
-                    // keep the title friendly.
-                    msgId = R.string.no_change;
-                    titleId = R.string.voicemail;
-                    // Set Button 2
-                    b.setNegativeButton(R.string.close_dialog, this);
-                    break;
-                case VM_RESPONSE_ERROR:
-                    msgId = R.string.vm_change_failed;
-                    // Set Button 1
-                    b.setPositiveButton(R.string.close_dialog, this);
-                    break;
-                case FW_SET_RESPONSE_ERROR:
-                    msgId = R.string.fw_change_failed;
-                    // Set Button 1
-                    b.setPositiveButton(R.string.close_dialog, this);
-                    break;
-                case FW_GET_RESPONSE_ERROR:
-                    msgId = R.string.fw_get_in_vm_failed;
-                    b.setPositiveButton(R.string.alert_dialog_yes, this);
-                    b.setNegativeButton(R.string.alert_dialog_no, this);
-                    break;
-                default:
-                    msgId = R.string.exception_error;
-                    // Set Button 3, tells the activity that the error is
-                    // not recoverable on dialog exit.
-                    b.setNeutralButton(R.string.close_dialog, this);
-                    break;
-            }
-
-            b.setTitle(getText(titleId));
-            String message = getText(msgId).toString();
-            b.setMessage(message);
-            b.setCancelable(false);
-            AlertDialog dialog = b.create();
-
-            // make the dialog more obvious by bluring the background.
-            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-
-            return dialog;
-        } else if (id == VOICEMAIL_FWD_SAVING_DIALOG || id == VOICEMAIL_FWD_READING_DIALOG ||
-                id == VOICEMAIL_REVERTING_DIALOG) {
-            ProgressDialog dialog = new ProgressDialog(this);
-            dialog.setTitle(getText(R.string.call_settings));
-            dialog.setIndeterminate(true);
-            dialog.setCancelable(false);
-            dialog.setMessage(getText(
-                    id == VOICEMAIL_FWD_SAVING_DIALOG ? R.string.updating_settings :
-                    (id == VOICEMAIL_REVERTING_DIALOG ? R.string.reverting_settings :
-                    R.string.reading_settings)));
-            return dialog;
-        }
-
-
-        return null;
+    protected Dialog onCreateDialog(int dialogId) {
+        return VoicemailDialogUtil.getDialog(this, dialogId);
     }
 
     // This is a method implemented for DialogInterface.OnClickListener.
@@ -1170,14 +1087,14 @@
         dialog.dismiss();
         switch (which){
             case DialogInterface.BUTTON_NEGATIVE:
-                if (mCurrentDialogId == FW_GET_RESPONSE_ERROR) {
+                if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
                     // We failed to get current forwarding settings and the user
                     // does not wish to continue.
                     switchToPreviousVoicemailProvider();
                 }
                 break;
             case DialogInterface.BUTTON_POSITIVE:
-                if (mCurrentDialogId == FW_GET_RESPONSE_ERROR) {
+                if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
                     // We failed to get current forwarding settings but the user
                     // wishes to continue changing settings to the new vm provider
                     saveVoiceMailAndForwardingNumberStage2();
@@ -1212,7 +1129,7 @@
         // Show the voicemail preference in onResume if the calling intent specifies the
         // ACTION_ADD_VOICEMAIL action.
         mShowVoicemailPreference = (icicle == null) &&
-                getIntent().getAction().equals(ACTION_ADD_VOICEMAIL);
+                TextUtils.equals(getIntent().getAction(), ACTION_ADD_VOICEMAIL);
 
         mSubscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
         mSubscriptionInfoHelper.setActionBarTitle(
diff --git a/src/com/android/phone/CallWaitingCheckBoxPreference.java b/src/com/android/phone/CallWaitingCheckBoxPreference.java
index ce2a420..bda8b3b 100644
--- a/src/com/android/phone/CallWaitingCheckBoxPreference.java
+++ b/src/com/android/phone/CallWaitingCheckBoxPreference.java
@@ -87,15 +87,20 @@
                 }
             }
 
-            if (ar.exception != null) {
+            if (ar.exception instanceof CommandException) {
                 if (DBG) {
-                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: ar.exception=" + ar.exception);
+                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: CommandException=" +
+                            ar.exception);
                 }
                 if (mTcpListener != null) {
                     mTcpListener.onException(CallWaitingCheckBoxPreference.this,
                             (CommandException)ar.exception);
                 }
-            } else if (ar.userObj instanceof Throwable) {
+            } else if (ar.userObj instanceof Throwable || ar.exception != null) {
+                // Still an error case but just not a CommandException.
+                if (DBG) {
+                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: Exception" + ar.exception);
+                }
                 if (mTcpListener != null) {
                     mTcpListener.onError(CallWaitingCheckBoxPreference.this, RESPONSE_ERROR);
                 }
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 3c385f9..306a653 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -20,9 +20,13 @@
 import com.android.ims.ImsException;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import android.app.ActionBar;
 import android.app.AlertDialog;
 import android.content.Context;
@@ -41,13 +45,22 @@
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
 import android.preference.SwitchPreference;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TabHost;
+import android.widget.TabHost.OnTabChangeListener;
+import android.widget.TabHost.TabContentFactory;
+import android.widget.TabHost.TabSpec;
+import android.widget.TabWidget;
 
 /**
  * "Mobile network settings" screen.  This preference screen lets you
@@ -96,12 +109,17 @@
     private Preference mLteDataServicePref;
 
     private static final String iface = "rmnet0"; //TODO: this will go away
+    private List<SubscriptionInfo> mSelectableSubInfos = null;
 
     private UserManager mUm;
     private Phone mPhone;
     private MyHandler mHandler;
     private boolean mOkClicked;
 
+    private TabHost mTabHost;
+    private TabWidget mTabWidget;
+    private ListView mListView;
+
     //GsmUmts options and Cdma options
     GsmUmtsOptions mGsmUmtsOptions;
     CdmaOptions mCdmaOptions;
@@ -137,6 +155,7 @@
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
         /** TODO: Refactor and get rid of the if's using subclasses */
+        final int phoneSubId = mPhone.getSubId();
         if (preference.getKey().equals(BUTTON_4G_LTE_KEY)) {
             return true;
         } else if (mGsmUmtsOptions != null &&
@@ -158,7 +177,8 @@
         } else if (preference == mButtonPreferredNetworkMode) {
             //displays the value taken from the Settings.System
             int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
-                    getContentResolver(), android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                    getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                     preferredNetworkMode);
             mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
             return true;
@@ -182,7 +202,8 @@
             return true;
         }  else if (preference == mButtonEnabledNetworks) {
             int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
-                    getContentResolver(), android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                    getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                     preferredNetworkMode);
             mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
             return true;
@@ -206,10 +227,46 @@
                   android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, value);
     }
 
+    private OnTabChangeListener mTabListener = new OnTabChangeListener() {
+        @Override
+        public void onTabChanged(String tabId) {
+            final int slotId = Integer.parseInt(tabId);
+            final SubscriptionInfo sir = findRecordBySlotId(slotId);
+            mPhone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(sir.getSubscriptionId()));
+
+            // The User has changed tab; update the body.
+            updateBody();
+        }
+    };
+
+    private TabContentFactory mEmptyTabContent = new TabContentFactory() {
+        @Override
+        public View createTabContent(String tag) {
+            return new View(mTabHost.getContext());
+        }
+    };
+
+    private TabSpec buildTabSpec(String tag, String title) {
+        return mTabHost.newTabSpec(tag).setIndicator(title).setContent(
+                mEmptyTabContent);
+    }
+
     @Override
     protected void onCreate(Bundle icicle) {
         setTheme(R.style.Theme_Material_Settings);
         super.onCreate(icicle);
+        final Context context = getApplicationContext();
+
+        mSelectableSubInfos = new ArrayList<SubscriptionInfo>();
+        final TelephonyManager tm =
+                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+
+        for (int i = 0; i < tm.getSimCount(); i++) {
+            SubscriptionInfo sir = findRecordBySlotId(i);
+            if (sir != null) {
+                mSelectableSubInfos.add(sir);
+            }
+        }
 
         mPhone = PhoneGlobals.getPhone();
         mHandler = new MyHandler();
@@ -250,10 +307,79 @@
 
         mLteDataServicePref = prefSet.findPreference(BUTTON_CDMA_LTE_DATA_SERVICE_KEY);
 
+        if (mSelectableSubInfos.size() > 1) {
+            setContentView(R.layout.network_settings);
+
+            mTabHost = (TabHost) findViewById(android.R.id.tabhost);
+            mTabWidget = (TabWidget) findViewById(android.R.id.tabs);
+            mListView = (ListView) findViewById(android.R.id.list);
+
+            mTabHost.setup();
+            mTabHost.setOnTabChangedListener(mTabListener);
+            mTabHost.clearAllTabs();
+
+            for (int i = 0; i < mSelectableSubInfos.size(); i++) {
+                mTabHost.addTab(buildTabSpec(String.valueOf(i),
+                        String.valueOf(mSelectableSubInfos.get(i).getDisplayName())));
+            }
+        }
+
+        updateBody();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        if (mUnavailable) {
+            return;
+        }
+
+        // upon resumption from the sub-activity, make sure we re-enable the
+        // preferences.
+        getPreferenceScreen().setEnabled(true);
+
+        // Set UI state in onResume because a user could go home, launch some
+        // app to change this setting's backend, and re-launch this settings app
+        // and the UI state would be inconsistent with actual state
+        mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
+
+        if (getPreferenceScreen().findPreference(BUTTON_PREFERED_NETWORK_MODE) != null)  {
+            mPhone.getPreferredNetworkType(mHandler.obtainMessage(
+                    MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
+        }
+
+        if (getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null)  {
+            mPhone.getPreferredNetworkType(mHandler.obtainMessage(
+                    MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
+        }
+    }
+
+    private void updateBody() {
+        final Context context = getApplicationContext();
+        final TelephonyManager tm =
+                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        PreferenceScreen prefSet = getPreferenceScreen();
         boolean isLteOnCdma = mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
+        final int phoneSubId = mPhone.getSubId();
+
+        if (prefSet != null) {
+            prefSet.removeAll();
+            prefSet.addPreference(mButtonDataRoam);
+            prefSet.addPreference(mButtonPreferredNetworkMode);
+            prefSet.addPreference(mButtonEnabledNetworks);
+        }
+
+        int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                mPhone.getContext().getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                preferredNetworkMode);
+
         mIsGlobalCdma = isLteOnCdma && getResources().getBoolean(R.bool.config_show_cdma);
-        TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-        if (tm.getSimplifiedNetworkSettingsEnabledForSubscriber(SubscriptionManager.getDefaultSubId())) {
+        int shouldHideCarrierSettings = android.provider.Settings.Global.getInt(
+                mPhone.getContext().getContentResolver(),
+                android.provider.Settings.Global.HIDE_CARRIER_NETWORK_SETTINGS, 0);
+        if (shouldHideCarrierSettings == 1 ) {
             prefSet.removePreference(mButtonPreferredNetworkMode);
             prefSet.removePreference(mButtonEnabledNetworks);
             prefSet.removePreference(mLteDataServicePref);
@@ -263,11 +389,6 @@
             // change Preferred Network Mode.
             mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
 
-            //Get the networkMode from Settings.System and displays it
-            int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
-                    getContentResolver(),android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
-                    preferredNetworkMode);
-            mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
             mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
             mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet);
         } else {
@@ -323,12 +444,7 @@
                         R.array.preferred_network_mode_values_world_mode);
             }
             mButtonEnabledNetworks.setOnPreferenceChangeListener(this);
-            int settingsNetworkMode = android.provider.Settings.Global.getInt(
-                    mPhone.getContext().getContentResolver(),
-                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
-                    preferredNetworkMode);
             if (DBG) log("settingsNetworkMode: " + settingsNetworkMode);
-            mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
         }
 
         final boolean missingDataServiceUrl = TextUtils.isEmpty(
@@ -366,34 +482,13 @@
                 root.removePreference(ps);
             }
         }
-    }
 
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        if (mUnavailable) {
-            return;
-        }
-
-        // upon resumption from the sub-activity, make sure we re-enable the
-        // preferences.
-        getPreferenceScreen().setEnabled(true);
-
-        // Set UI state in onResume because a user could go home, launch some
-        // app to change this setting's backend, and re-launch this settings app
-        // and the UI state would be inconsistent with actual state
+        //Get the networkMode from Settings.System and displays it
         mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
-
-        if (getPreferenceScreen().findPreference(BUTTON_PREFERED_NETWORK_MODE) != null)  {
-            mPhone.getPreferredNetworkType(mHandler.obtainMessage(
-                    MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
-        }
-
-        if (getPreferenceScreen().findPreference(BUTTON_ENABLED_NETWORKS_KEY) != null)  {
-            mPhone.getPreferredNetworkType(mHandler.obtainMessage(
-                    MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
-        }
+        mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
+        mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
+        UpdatePreferredNetworkModeSummary(settingsNetworkMode);
+        UpdateEnabledNetworksValueAndSummary(settingsNetworkMode);
     }
 
     @Override
@@ -410,6 +505,7 @@
      * display value.
      */
     public boolean onPreferenceChange(Preference preference, Object objValue) {
+        final int phoneSubId = mPhone.getSubId();
         if (preference == mButtonPreferredNetworkMode) {
             //NOTE onPreferenceChange seems to be called even if there is no change
             //Check if the button value is changed from the System.Setting
@@ -418,7 +514,8 @@
             buttonNetworkMode = Integer.valueOf((String) objValue).intValue();
             int settingsNetworkMode = android.provider.Settings.Global.getInt(
                     mPhone.getContext().getContentResolver(),
-                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                    preferredNetworkMode);
             if (buttonNetworkMode != settingsNetworkMode) {
                 int modemNetworkMode;
                 // if new mode is invalid ignore it
@@ -447,7 +544,7 @@
                 UpdatePreferredNetworkModeSummary(buttonNetworkMode);
 
                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         buttonNetworkMode );
                 //Set the modem network mode
                 mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
@@ -460,7 +557,8 @@
             if (DBG) log("buttonNetworkMode: " + buttonNetworkMode);
             int settingsNetworkMode = android.provider.Settings.Global.getInt(
                     mPhone.getContext().getContentResolver(),
-                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
+                    preferredNetworkMode);
             if (buttonNetworkMode != settingsNetworkMode) {
                 int modemNetworkMode;
                 // if new mode is invalid ignore it
@@ -483,7 +581,7 @@
                 UpdateEnabledNetworksValueAndSummary(buttonNetworkMode);
 
                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         buttonNetworkMode );
                 //Set the modem network mode
                 mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
@@ -548,6 +646,7 @@
         }
 
         private void handleGetPreferredNetworkTypeResponse(Message msg) {
+            final int phoneSubId = mPhone.getSubId();
             AsyncResult ar = (AsyncResult) msg.obj;
 
             if (ar.exception == null) {
@@ -560,7 +659,7 @@
 
                 int settingsNetworkMode = android.provider.Settings.Global.getInt(
                         mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         preferredNetworkMode);
 
                 if (DBG) {
@@ -614,17 +713,18 @@
 
         private void handleSetPreferredNetworkTypeResponse(Message msg) {
             AsyncResult ar = (AsyncResult) msg.obj;
+            final int phoneSubId = mPhone.getSubId();
 
             if (ar.exception == null) {
                 int networkMode = Integer.valueOf(
                         mButtonPreferredNetworkMode.getValue()).intValue();
                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         networkMode );
                 networkMode = Integer.valueOf(
                         mButtonEnabledNetworks.getValue()).intValue();
                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         networkMode );
             } else {
                 mPhone.getPreferredNetworkType(obtainMessage(MESSAGE_GET_PREFERRED_NETWORK_TYPE));
@@ -632,12 +732,13 @@
         }
 
         private void resetNetworkModeToDefault() {
+            final int phoneSubId = mPhone.getSubId();
             //set the mButtonPreferredNetworkMode
             mButtonPreferredNetworkMode.setValue(Integer.toString(preferredNetworkMode));
             mButtonEnabledNetworks.setValue(Integer.toString(preferredNetworkMode));
             //set the Settings.System
             android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         preferredNetworkMode );
             //Set the Modem
             mPhone.setPreferredNetworkType(preferredNetworkMode,
@@ -924,4 +1025,24 @@
             systemSelect.setEnabled(enable);
         }
     }
+
+    /**
+     * finds a record with slotId.
+     * Since the number of SIMs are few, an array is fine.
+     */
+    public static SubscriptionInfo findRecordBySlotId(final int slotId) {
+        final List<SubscriptionInfo> subInfoList =
+            SubscriptionManager.getActiveSubscriptionInfoList();
+        final int subInfoLength = subInfoList.size();
+
+        for (int i = 0; i < subInfoLength; ++i) {
+            final SubscriptionInfo sir = subInfoList.get(i);
+            if (sir.getSimSlotIndex() == slotId) {
+                //Right now we take the first subscription on a SIM.
+                return sir;
+            }
+        }
+
+        return null;
+    }
 }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index e3d1a08..f0e37f2 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -47,7 +47,7 @@
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
@@ -140,8 +140,6 @@
     SharedPreferences mTelephonySharedPreferences;
     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
-    private static final String PREF_CARRIERS_SIMPLIFIED_NETWORK_SETTINGS_PREFIX =
-            "carrier_simplified_network_settings_";
     private static final String PREF_ENABLE_VIDEO_CALLING = "enable_video_calling";
 
     /**
@@ -771,8 +769,8 @@
         }
 
         boolean isValid = false;
-        List<SubInfoRecord> slist = SubscriptionManager.getActiveSubInfoList();
-        for (SubInfoRecord subInfoRecord : slist) {
+        List<SubscriptionInfo> slist = SubscriptionManager.getActiveSubscriptionInfoList();
+        for (SubscriptionInfo subInfoRecord : slist) {
             if (subInfoRecord.getSubscriptionId() == subId) {
                 isValid = true;
                 break;
@@ -1853,12 +1851,13 @@
     @Override
     public boolean setPreferredNetworkType(int networkType) {
         enforceModifyPermissionOrCarrierPrivilege();
+        final int phoneSubId = mPhone.getSubId();
         if (DBG) log("setPreferredNetworkType: type " + networkType);
         Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType);
         if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
         if (success) {
             Settings.Global.putInt(mPhone.getContext().getContentResolver(),
-                    Settings.Global.PREFERRED_NETWORK_MODE, networkType);
+                    Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId, networkType);
         }
         return success;
     }
@@ -1943,34 +1942,6 @@
     }
 
     @Override
-    public void enableSimplifiedNetworkSettingsForSubscriber(int subId, boolean enable) {
-        enforceModifyPermissionOrCarrierPrivilege();
-
-        String iccId = getIccId(subId);
-        if (iccId != null) {
-            String snsPrefKey = PREF_CARRIERS_SIMPLIFIED_NETWORK_SETTINGS_PREFIX + iccId;
-            SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
-            if (enable) {
-                editor.putBoolean(snsPrefKey, true);
-            } else {
-                editor.remove(snsPrefKey);
-            }
-            editor.commit();
-        }
-    }
-
-    @Override
-    public boolean getSimplifiedNetworkSettingsEnabledForSubscriber(int subId) {
-        enforceReadPermission();
-        String iccId = getIccId(subId);
-        if (iccId != null) {
-            String snsPrefKey = PREF_CARRIERS_SIMPLIFIED_NETWORK_SETTINGS_PREFIX + iccId;
-            return mTelephonySharedPreferences.getBoolean(snsPrefKey, false);
-        }
-        return false;
-    }
-
-    @Override
     public void setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number) {
         enforceModifyPermissionOrCarrierPrivilege();
 
diff --git a/src/com/android/phone/SubscriptionInfoHelper.java b/src/com/android/phone/SubscriptionInfoHelper.java
index 926a156..1255452 100644
--- a/src/com/android/phone/SubscriptionInfoHelper.java
+++ b/src/com/android/phone/SubscriptionInfoHelper.java
@@ -20,7 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
 
@@ -75,7 +75,7 @@
         return intent;
     }
 
-    public static void addExtrasToIntent(Intent intent, SubInfoRecord subscription) {
+    public static void addExtrasToIntent(Intent intent, SubscriptionInfo subscription) {
         intent.putExtra(SubscriptionInfoHelper.SUB_ID_EXTRA, subscription.getSubscriptionId());
         intent.putExtra(
                 SubscriptionInfoHelper.SUB_LABEL_EXTRA, subscription.getDisplayName().toString());
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 5226e0d..a99c5f0 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -12,7 +12,7 @@
 import android.preference.PreferenceFragment;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
@@ -297,7 +297,7 @@
     }
 
     private void initAccountList() {
-        for (SubInfoRecord subscription : SubscriptionManager.getActiveSubInfoList()) {
+        for (SubscriptionInfo subscription : SubscriptionManager.getActiveSubscriptionInfoList()) {
             CharSequence label = subscription.getDisplayName();
             Intent intent = new Intent(TelecomManager.ACTION_SHOW_CALL_SETTINGS);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/phone/settings/VoicemailDialogUtil.java b/src/com/android/phone/settings/VoicemailDialogUtil.java
new file mode 100644
index 0000000..0a9e4bc
--- /dev/null
+++ b/src/com/android/phone/settings/VoicemailDialogUtil.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.phone.settings;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.view.WindowManager;
+
+import com.android.phone.CallFeaturesSetting;
+import com.android.phone.R;
+
+public class VoicemailDialogUtil {
+
+    // Voicemail dialog identifiers.
+    public static final int VM_NOCHANGE_ERROR_DIALOG = 400;
+    public static final int VM_RESPONSE_ERROR_DIALOG = 500;
+    public static final int FWD_SET_RESPONSE_ERROR_DIALOG = 501;
+    public static final int FWD_GET_RESPONSE_ERROR_DIALOG = 502;
+    public static final int VM_CONFIRM_DIALOG = 600;
+    public static final int VM_FWD_SAVING_DIALOG = 601;
+    public static final int VM_FWD_READING_DIALOG = 602;
+    public static final int VM_REVERTING_DIALOG = 603;
+
+    public static Dialog getDialog(CallFeaturesSetting parent, int id) {
+        if ((id == VM_RESPONSE_ERROR_DIALOG) || (id == VM_NOCHANGE_ERROR_DIALOG) ||
+            (id == FWD_SET_RESPONSE_ERROR_DIALOG) || (id == FWD_GET_RESPONSE_ERROR_DIALOG) ||
+                (id == VM_CONFIRM_DIALOG)) {
+
+            AlertDialog.Builder b = new AlertDialog.Builder(parent);
+
+            int msgId;
+            int titleId = R.string.error_updating_title;
+            switch (id) {
+                case VM_CONFIRM_DIALOG:
+                    msgId = R.string.vm_changed;
+                    titleId = R.string.voicemail;
+                    // Set Button 2
+                    b.setNegativeButton(R.string.close_dialog, parent);
+                    break;
+                case VM_NOCHANGE_ERROR_DIALOG:
+                    // even though this is technically an error,
+                    // keep the title friendly.
+                    msgId = R.string.no_change;
+                    titleId = R.string.voicemail;
+                    // Set Button 2
+                    b.setNegativeButton(R.string.close_dialog, parent);
+                    break;
+                case VM_RESPONSE_ERROR_DIALOG:
+                    msgId = R.string.vm_change_failed;
+                    // Set Button 1
+                    b.setPositiveButton(R.string.close_dialog, parent);
+                    break;
+                case FWD_SET_RESPONSE_ERROR_DIALOG:
+                    msgId = R.string.fw_change_failed;
+                    // Set Button 1
+                    b.setPositiveButton(R.string.close_dialog, parent);
+                    break;
+                case FWD_GET_RESPONSE_ERROR_DIALOG:
+                    msgId = R.string.fw_get_in_vm_failed;
+                    b.setPositiveButton(R.string.alert_dialog_yes, parent);
+                    b.setNegativeButton(R.string.alert_dialog_no, parent);
+                    break;
+                default:
+                    msgId = R.string.exception_error;
+                    // Set Button 3, tells the activity that the error is
+                    // not recoverable on dialog exit.
+                    b.setNeutralButton(R.string.close_dialog, parent);
+                    break;
+            }
+
+            b.setTitle(parent.getText(titleId));
+            String message = parent.getText(msgId).toString();
+            b.setMessage(message);
+            b.setCancelable(false);
+            AlertDialog dialog = b.create();
+
+            // make the dialog more obvious by bluring the background.
+            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+            return dialog;
+        } else if (id == VM_FWD_SAVING_DIALOG || id == VM_FWD_READING_DIALOG ||
+                id == VM_REVERTING_DIALOG) {
+            ProgressDialog dialog = new ProgressDialog(parent);
+            dialog.setTitle(parent.getText(R.string.call_settings));
+            dialog.setIndeterminate(true);
+            dialog.setCancelable(false);
+            dialog.setMessage(parent.getText(
+                    id == VM_FWD_SAVING_DIALOG ? R.string.updating_settings :
+                    (id == VM_REVERTING_DIALOG ? R.string.reverting_settings :
+                    R.string.reading_settings)));
+            return dialog;
+        }
+
+        return null;
+    }
+}
diff --git a/src/com/android/services/telephony/CdmaConference.java b/src/com/android/services/telephony/CdmaConference.java
index 5372548..2d5ee47 100755
--- a/src/com/android/services/telephony/CdmaConference.java
+++ b/src/com/android/services/telephony/CdmaConference.java
@@ -37,15 +37,15 @@
 
     private int mCapabilities = PhoneCapabilities.MUTE;
 
-    public CdmaConference(PhoneAccountHandle phoneAccount, int capabilities) {
+    public CdmaConference(PhoneAccountHandle phoneAccount) {
         super(phoneAccount);
-        setCapabilities(mCapabilities | capabilities);
         setActive();
     }
 
     private void updateCapabilities() {
         setCapabilities(mCapabilities);
     }
+
     /**
      * Invoked when the Conference and all it's {@link Connection}s should be disconnected.
      */
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
index d6d5659..e2f0b50 100644
--- a/src/com/android/services/telephony/CdmaConferenceController.java
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -149,18 +149,20 @@
             // 1) Create a new conference connection if it doesn't exist.
             if (mConference == null) {
                 Log.i(this, "Creating new Cdma conference call");
-                CdmaConnection newConnection = mCdmaConnections.get(mCdmaConnections.size() - 1);
-                if (newConnection.isOutgoing()) {
-                    // Only an outgoing call can be merged with an ongoing call.
-                    mConference = new CdmaConference(null, PhoneCapabilities.MERGE_CONFERENCE);
-                } else {
-                    // If the most recently added connection was an incoming call, enable
-                    // swap instead of merge.
-                    mConference = new CdmaConference(null, PhoneCapabilities.SWAP_CONFERENCE);
-                }
+                mConference = new CdmaConference(null);
                 isNewlyCreated = true;
             }
 
+            CdmaConnection newConnection = mCdmaConnections.get(mCdmaConnections.size() - 1);
+            if (newConnection.isOutgoing()) {
+                // Only an outgoing call can be merged with an ongoing call.
+                mConference.setCapabilities(PhoneCapabilities.MERGE_CONFERENCE);
+            } else {
+                // If the most recently added connection was an incoming call, enable
+                // swap instead of merge.
+                mConference.setCapabilities(PhoneCapabilities.SWAP_CONFERENCE);
+            }
+
             // 2) Add any new connections to the conference
             List<Connection> existingChildConnections =
                     new ArrayList<>(mConference.getConnections());
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 49767a2..3523288 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -16,11 +16,9 @@
 
 package com.android.services.telephony;
 
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
+import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.telecom.PhoneAccount;
@@ -28,7 +26,8 @@
 import android.telecom.TelecomManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
-import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionListener;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -36,7 +35,6 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.PhoneProxy;
-import com.android.internal.telephony.TelephonyIntents;
 import com.android.phone.R;
 
 import java.util.Arrays;
@@ -50,26 +48,6 @@
 final class TelecomAccountRegistry {
     private static final boolean DBG = false; /* STOP SHIP if true */
 
-    // Slot IDs are zero based indices but the numbered icons represent the first, second,
-    // etc... SIM in the device. So that means that index 0 is SIM 1, index 1 is SIM 2 and so on.
-
-    private final static int[] phoneAccountIcons = {
-            R.drawable.ic_multi_sim1,
-            R.drawable.ic_multi_sim2,
-            R.drawable.ic_multi_sim3,
-            R.drawable.ic_multi_sim4
-    };
-
-    private final static int[] colors = {
-        0xff00796b,
-        0xff3367d6,
-        0xff303f9f,
-        0xff7b1fa2,
-        0xffc2185b,
-        0xffc53929
-    };
-
-
     // This icon is the one that is used when the Slot ID that we have for a particular SIM
     // is not supported, i.e. SubscriptionManager.INVALID_SLOT_ID or the 5th SIM in a phone.
     private final static int defaultPhoneAccountIcon =  R.drawable.ic_multi_sim;
@@ -116,6 +94,7 @@
 
             String label;
             String description;
+            Bitmap iconBitmap = null;
 
             if (isEmergency) {
                 label = mContext.getResources().getString(R.string.sim_label_emergency_calls);
@@ -129,13 +108,12 @@
                 CharSequence subDisplayName = null;
                 // We can only get the real slotId from the SubInfoRecord, we can't calculate the
                 // slotId from the subId or the phoneId in all instances.
-                SubInfoRecord record = SubscriptionManager.getSubInfoForSubscriber(subId);
+                SubscriptionInfo record = SubscriptionManager.getSubscriptionInfoForSubscriber(subId);
                 if (record != null) {
                     subDisplayName = record.getDisplayName();
-                    slotId = record.getSubscriptionId();
-
-                    // Assign a "fake" color while the underlying Telephony stuff is refactored.
-                    color = makeFakeColor(subId);
+                    slotId = record.getSimSlotIndex();
+                    color = record.getIconTint();
+                    iconBitmap = record.createIconBitmap(mContext);
                 }
 
                 String slotIdString;
@@ -164,15 +142,19 @@
                     PhoneAccount.CAPABILITY_CALL_PROVIDER |
                     PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS;
 
+            if (iconBitmap == null) {
+                iconBitmap = BitmapFactory.decodeResource(
+                        mContext.getResources(),
+                        defaultPhoneAccountIcon);
+            }
+
             PhoneAccount account = PhoneAccount.builder(phoneAccountHandle, label)
                     .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, line1Number, null))
                     .setSubscriptionAddress(
                             Uri.fromParts(PhoneAccount.SCHEME_TEL, subNumber, null))
                     .setCapabilities(capabilities)
-                    .setIconBitmap(BitmapFactory.decodeResource(
-                            mContext.getResources(),
-                            getPhoneAccountIcon(slotId)))
-                    .setColor(color)
+                    .setIcon(iconBitmap)
+                    .setHighlightColor(color)
                     .setShortDescription(description)
                     .setSupportedUriSchemes(Arrays.asList(
                             PhoneAccount.SCHEME_TEL, PhoneAccount.SCHEME_VOICEMAIL))
@@ -188,35 +170,12 @@
         }
     }
 
-    private int makeFakeColor(long subId) {
-        return colors[((int) subId) % colors.length];
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+    private final SubscriptionListener mSubscriptionListener = new SubscriptionListener() {
         @Override
-        public void onReceive(Context context, Intent intent) {
-            boolean rebuildAccounts = false;
-            String action = intent.getAction();
-            if (TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED.equals(action)) {
-                int status = intent.getIntExtra(
-                        SubscriptionManager.INTENT_KEY_DETECT_STATUS,
-                        SubscriptionManager.EXTRA_VALUE_NOCHANGE);
-                Log.i(this, "SUBINFO_RECORD_UPDATED : %d.", status);
-                // Anytime the SIM state changes...rerun the setup
-                // We rely on this notification even when the status is EXTRA_VALUE_NOCHANGE,
-                // so we explicitly do not check for that here.
-                rebuildAccounts = true;
-            } else if (TelephonyIntents.ACTION_SUBINFO_CONTENT_CHANGE.equals(action)) {
-                String columnName = intent.getStringExtra(TelephonyIntents.EXTRA_COLUMN_NAME);
-                String stringContent = intent.getStringExtra(TelephonyIntents.EXTRA_STRING_CONTENT);
-                Log.v(this, "SUBINFO_CONTENT_CHANGE: Column: %s Content: %s",
-                        columnName, stringContent);
-                rebuildAccounts = true;
-            }
-            if (rebuildAccounts) {
-                tearDownAccounts();
-                setupAccounts();
-            }
+        public void onSubscriptionInfoChanged() {
+            // Any time the SubscriptionInfo changes...rerun the setup
+            tearDownAccounts();
+            setupAccounts();
         }
     };
 
@@ -256,12 +215,14 @@
      * Sets up all the phone accounts for SIMs on first boot.
      */
     void setupOnBoot() {
-        // We need to register for both types of intents if we want to see added/removed Subs
-        // along with changes to a given Sub.
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_RECORD_UPDATED);
-        intentFilter.addAction(TelephonyIntents.ACTION_SUBINFO_CONTENT_CHANGE);
-        mContext.registerReceiver(mReceiver, intentFilter);
+        // TODO: When this object "finishes" we should unregister by invoking
+        // SubscriptionManager.unregister(mContext, mSubscriptionListener);
+        // This is not strictly necessary because it will be unregistered if the
+        // notification fails but it is good form.
+
+        // Register for SubscriptionInfo list changes
+        SubscriptionManager.register(mContext, mSubscriptionListener,
+                SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED);
 
         // We also need to listen for changes to the service state (e.g. emergency -> in service)
         // because this could signal a removal or addition of a SIM in a single SIM phone.
@@ -345,16 +306,6 @@
         cleanupPhoneAccounts();
     }
 
-    private int getPhoneAccountIcon(int index) {
-        // A valid slot id doesn't necessarily mean that we have an icon for it.
-        if (SubscriptionManager.isValidSlotId(index) &&
-                index < TelecomAccountRegistry.phoneAccountIcons.length) {
-            return TelecomAccountRegistry.phoneAccountIcons[index];
-        }
-        // Invalid indices get the default icon that has no number associated with it.
-        return defaultPhoneAccountIcon;
-    }
-
     private void tearDownAccounts() {
         for (AccountEntry entry : mAccounts) {
             entry.teardown();