Merge "Update PhoneGlobals, PhoneInterfaceManager and CdmaConference to use carrierconfig." into mnc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 764afe7..59d0753 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -516,6 +516,15 @@
             </intent-filter>
         </receiver>
 
+        <activity android:name="com.android.services.telephony.sip.SipPhoneAccountSettingsActivity"
+                android:theme="@android:style/Theme.NoDisplay"
+                android:excludeFromRecents="true">
+            <intent-filter>
+                <action android:name="android.telecom.action.CONNECTION_SERVICE_CONFIGURE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity android:label="Sip Settings"
                   android:name="com.android.services.telephony.sip.SipSettings"
                   android:theme="@style/DialerSettingsLight"
diff --git a/res/color/default_sim_icon_tint_color.xml b/res/color/default_sim_icon_tint_color.xml
new file mode 100644
index 0000000..100a969
--- /dev/null
+++ b/res/color/default_sim_icon_tint_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2015 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.
+ */
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="#FF555555"/>
+</selector>
diff --git a/res/values/config.xml b/res/values/config.xml
index 3683b06..61af525 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -162,5 +162,5 @@
 
     <!-- Disables dialing "*228" (OTASP provisioning) on CDMA carriers where it is not supported or
          is potentially harmful by locking the SIM to 3G. -->
-    <string name="config_disable_cdma_activation_code">false</string>
+    <string name="config_disable_cdma_activation_code" translatable="false">false</string>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 260de24..e707c4e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1255,10 +1255,6 @@
         <item>never</item>
     </string-array>
 
-    <!--  Setting option name to enable or disable dialpad autocomplete functionality
-         [CHAR LIMIT=30] -->
-    <string name="dial_pad_autocomplete">Dialpad autocomplete</string>
-
     <!-- Title for the category "ringtone", which is shown above ringtone and vibration
          related settings.
          [CHAR LIMIT=30] -->
diff --git a/res/xml/phone_account_settings.xml b/res/xml/phone_account_settings.xml
index ff01d34..119accd 100644
--- a/res/xml/phone_account_settings.xml
+++ b/res/xml/phone_account_settings.xml
@@ -20,21 +20,15 @@
 
     <PreferenceCategory
         android:key="phone_accounts_accounts_list_category_key"
-        android:title="@string/phone_accounts_settings_header" />
+        android:title="@string/phone_accounts_settings_header">
 
-    <com.android.phone.settings.AccountSelectionPreference
-        android:key="default_outgoing_account"
-        android:title="@string/phone_accounts_make_calls_with"
-        android:defaultValue=""
-        android:persistent="false" />
+        <com.android.phone.settings.AccountSelectionPreference
+            android:key="default_outgoing_account"
+            android:title="@string/phone_accounts_make_calls_with"
+            android:defaultValue=""
+            android:persistent="false" />
 
-    <com.android.phone.settings.TtyModeListPreference
-        android:key="@string/tty_mode_key"
-        android:title="@string/tty_mode_option_title"
-        android:summary="@string/tty_mode_option_summary"
-        android:persistent="false"
-        android:entries="@array/tty_mode_entries"
-        android:entryValues="@array/tty_mode_values"/>
+    </PreferenceCategory>
 
     <PreferenceCategory
         android:key="phone_accounts_call_assistant_settings_category_key"
diff --git a/sip/src/com/android/services/telephony/sip/SipPhoneAccountSettingsActivity.java b/sip/src/com/android/services/telephony/sip/SipPhoneAccountSettingsActivity.java
new file mode 100644
index 0000000..0455346
--- /dev/null
+++ b/sip/src/com/android/services/telephony/sip/SipPhoneAccountSettingsActivity.java
@@ -0,0 +1,62 @@
+/*
+ * 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.services.telephony.sip;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.sip.SipProfile;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.util.Log;
+
+/**
+ * This activity receives the standard telecom intent to open settings for a PhoneAccount. It
+ * translates the incoming phone account to a SIP profile and opens the corresponding
+ * PreferenceActivity for said profile.
+ */
+public final class SipPhoneAccountSettingsActivity extends Activity {
+    private static final String TAG = "SipSettingsActivity";
+
+    /** ${inheritDoc} */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent intent = getIntent();
+        Log.i(TAG, "" + intent);
+        if (intent != null) {
+            PhoneAccountHandle accountHandle = (PhoneAccountHandle)
+                    intent.getParcelableExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);
+            Log.i(TAG, "" + accountHandle);
+
+            if (accountHandle != null) {
+                SipProfileDb profileDb = new SipProfileDb(this);
+                String sipUri = SipUtil.getSipUriFromPhoneAccount(accountHandle);
+                SipProfile profile = profileDb.retrieveSipProfile(sipUri);
+                if (profile != null) {
+                    Intent settingsIntent = new Intent(this, SipEditor.class);
+                    settingsIntent.putExtra(SipSettings.KEY_SIP_PROFILE, (Parcelable) profile);
+                    startActivity(settingsIntent);
+                }
+            }
+        }
+
+        finish();
+    }
+}
diff --git a/sip/src/com/android/services/telephony/sip/SipProfileDb.java b/sip/src/com/android/services/telephony/sip/SipProfileDb.java
index 00e214f..5641af9 100644
--- a/sip/src/com/android/services/telephony/sip/SipProfileDb.java
+++ b/sip/src/com/android/services/telephony/sip/SipProfileDb.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.net.sip.SipProfile;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.File;
@@ -42,6 +43,8 @@
     private static final String PROFILES_DIR = "/profiles/";
     private static final String PROFILE_OBJ_FILE = ".pobj";
 
+    private static final String SCHEME_PREFIX = "sip:";
+
     private String mProfilesDirectory;
     private SipSharedPreferences mSipSharedPreferences;
     private int mProfilesCount = -1;
@@ -100,6 +103,15 @@
         }
     }
 
+    public SipProfile retrieveSipProfile(String sipUri) {
+        sipUri = sipUri.trim();
+        if (sipUri.startsWith(SCHEME_PREFIX)) {
+            return retrieveSipProfileFromName(sipUri.substring(SCHEME_PREFIX.length()));
+        }
+
+        return null;
+    }
+
     private List<SipProfile> retrieveSipProfileListInternal() {
         List<SipProfile> sipProfileList = Collections.synchronizedList(
                 new ArrayList<SipProfile>());
@@ -108,23 +120,35 @@
         String[] dirs = root.list();
         if (dirs == null) return sipProfileList;
         for (String dir : dirs) {
-            File f = new File(new File(root, dir), PROFILE_OBJ_FILE);
-            if (!f.exists()) continue;
-            try {
-                SipProfile p = deserialize(f);
-                if (p == null) continue;
-                if (!dir.equals(p.getProfileName())) continue;
-
-                sipProfileList.add(p);
-            } catch (IOException e) {
-                log("retrieveSipProfileListInternal, exception: " + e);
-            }
+            SipProfile p = retrieveSipProfileFromName(dir);
+            if (p == null) continue;
+            sipProfileList.add(p);
         }
         mProfilesCount = sipProfileList.size();
         mSipSharedPreferences.setProfilesCount(mProfilesCount);
         return sipProfileList;
     }
 
+    private SipProfile retrieveSipProfileFromName(String name) {
+        if (TextUtils.isEmpty(name)) {
+            return null;
+        }
+
+        File root = new File(mProfilesDirectory);
+        File f = new File(new File(root, name), PROFILE_OBJ_FILE);
+        if (f.exists()) {
+            try {
+                SipProfile p = deserialize(f);
+                if (p != null && name.equals(p.getProfileName())) {
+                    return p;
+                }
+            } catch (IOException e) {
+                log("retrieveSipProfileListInternal, exception: " + e);
+            }
+        }
+        return null;
+    }
+
     private SipProfile deserialize(File profileObjectFile) throws IOException {
         AtomicFile atomicFile = new AtomicFile(profileObjectFile);
         ObjectInputStream ois = null;
diff --git a/sip/src/com/android/services/telephony/sip/SipSettings.java b/sip/src/com/android/services/telephony/sip/SipSettings.java
index 7da0131..b89a5b1 100644
--- a/sip/src/com/android/services/telephony/sip/SipSettings.java
+++ b/sip/src/com/android/services/telephony/sip/SipSettings.java
@@ -57,25 +57,20 @@
  * The PreferenceActivity class for managing sip profile preferences.
  */
 public class SipSettings extends PreferenceActivity {
-    private static final String PREFIX = "[SipSettings] ";
-    private static final boolean VERBOSE = false; /* STOP SHIP if true */
-
     public static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES";
 
-    private static final int MENU_ADD_ACCOUNT = Menu.FIRST;
-
     static final String KEY_SIP_PROFILE = "sip_profile";
+    static final int REQUEST_ADD_OR_EDIT_SIP_PROFILE = 1;
 
+    private static final String PREFIX = "[SipSettings] ";
+    private static final boolean VERBOSE = false; /* STOP SHIP if true */
+    private static final int MENU_ADD_ACCOUNT = Menu.FIRST;
     private static final String PREF_SIP_LIST = "sip_account_list";
 
-    private static final int REQUEST_ADD_OR_EDIT_SIP_PROFILE = 1;
-
     private PackageManager mPackageManager;
     private SipManager mSipManager;
     private SipProfileDb mProfileDb;
-
     private SipProfile mProfile; // profile that's being edited
-
     private PreferenceCategory mSipListContainer;
     private Map<String, SipPreference> mSipPreferenceMap;
     private List<SipProfile> mSipProfileList;
@@ -144,8 +139,6 @@
         addPreferencesFromResource(R.xml.sip_setting);
         mSipListContainer = (PreferenceCategory) findPreference(PREF_SIP_LIST);
 
-        updateProfilesStatus();
-
         ActionBar actionBar = getActionBar();
         if (actionBar != null) {
             actionBar.setDisplayHomeAsUpEnabled(true);
@@ -155,6 +148,7 @@
     @Override
     public void onResume() {
         super.onResume();
+        updateProfilesStatus();
     }
 
     @Override
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index 96e9e7b..1a23bc4 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -16,6 +16,7 @@
 
 package com.android.phone;
 
+import android.Manifest;
 import android.app.Activity;
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
@@ -72,9 +73,6 @@
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
-    /** Required permission for any app that wants to consume ACTION_NEW_OUTGOING_CALL. */
-    private static final String PERMISSION = android.Manifest.permission.PROCESS_OUTGOING_CALLS;
-
     public static final String ACTION_SIP_SELECT_PHONE = "com.android.phone.SIP_SELECT_PHONE";
     public static final String EXTRA_ALREADY_CALLED = "android.phone.extra.ALREADY_CALLED";
     public static final String EXTRA_ORIGINAL_URI = "android.phone.extra.ORIGINAL_URI";
@@ -638,7 +636,9 @@
         mHandler.sendEmptyMessageDelayed(EVENT_OUTGOING_CALL_TIMEOUT,
                 OUTGOING_CALL_TIMEOUT_THRESHOLD);
         sendOrderedBroadcastAsUser(broadcastIntent, UserHandle.OWNER,
-                PERMISSION, new OutgoingCallReceiver(),
+                android.Manifest.permission.PROCESS_OUTGOING_CALLS,
+                AppOpsManager.OP_PROCESS_OUTGOING_CALLS,
+                new OutgoingCallReceiver(),
                 null,  // scheduler
                 Activity.RESULT_OK,  // initialCode
                 number,  // initialData: initial value for the result data
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index e71d1fb..fcef594 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -512,7 +512,11 @@
     }
 
     /* package */ Bundle getCarrierConfig() {
-        return configLoader.getConfigForSubId(SubscriptionManager.getDefaultSubId());
+        return getCarrierConfigForSubId(SubscriptionManager.getDefaultSubId());
+    }
+
+    /* package */ Bundle getCarrierConfigForSubId(int subId) {
+        return configLoader.getConfigForSubId(subId);
     }
 
     /**
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 7f04302..a4fd187 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -3,6 +3,11 @@
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
 import android.net.sip.SipManager;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -11,6 +16,7 @@
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceFragment;
+import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.SubscriptionInfo;
@@ -24,6 +30,9 @@
 import com.android.services.telephony.sip.SipSharedPreferences;
 import com.android.services.telephony.sip.SipUtil;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 
 public class PhoneAccountSettingsFragment extends PreferenceFragment
@@ -51,6 +60,7 @@
     private String LOG_TAG = PhoneAccountSettingsFragment.class.getSimpleName();
 
     private TelecomManager mTelecomManager;
+    private TelephonyManager mTelephonyManager;
     private SubscriptionManager mSubscriptionManager;
 
     private PreferenceCategory mAccountList;
@@ -68,6 +78,7 @@
         super.onCreate(icicle);
 
         mTelecomManager = TelecomManager.from(getActivity());
+        mTelephonyManager = TelephonyManager.from(getActivity());
         mSubscriptionManager = SubscriptionManager.from(getActivity());
     }
 
@@ -81,28 +92,22 @@
 
         addPreferencesFromResource(R.xml.phone_account_settings);
 
-        TelephonyManager telephonyManager =
-                (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
         mAccountList = (PreferenceCategory) getPreferenceScreen().findPreference(
                 ACCOUNTS_LIST_CATEGORY_KEY);
-        TtyModeListPreference ttyModeListPreference =
-                (TtyModeListPreference) getPreferenceScreen().findPreference(
-                        getResources().getString(R.string.tty_mode_key));
-        if (telephonyManager.isMultiSimEnabled()) {
+        if (shouldShowConnectionServiceList()) {
             initAccountList();
-            ttyModeListPreference.init();
-        } else {
-            getPreferenceScreen().removePreference(mAccountList);
-            getPreferenceScreen().removePreference(ttyModeListPreference);
-        }
 
-        mDefaultOutgoingAccount = (AccountSelectionPreference)
-                getPreferenceScreen().findPreference(DEFAULT_OUTGOING_ACCOUNT_KEY);
+            mDefaultOutgoingAccount = (AccountSelectionPreference)
+                    getPreferenceScreen().findPreference(DEFAULT_OUTGOING_ACCOUNT_KEY);
             mDefaultOutgoingAccount.setListener(this);
             if (mTelecomManager.getCallCapablePhoneAccounts().size() > 1) {
-            updateDefaultOutgoingAccountsModel();
+                updateDefaultOutgoingAccountsModel();
+            } else {
+                getPreferenceScreen().removePreference(mDefaultOutgoingAccount);
+            }
+
         } else {
-            getPreferenceScreen().removePreference(mDefaultOutgoingAccount);
+            getPreferenceScreen().removePreference(mAccountList);
         }
 
         List<PhoneAccountHandle> simCallManagers = mTelecomManager.getSimCallManagers();
@@ -287,8 +292,7 @@
      */
     public void updateCallAssistantModel() {
         mSelectCallAssistant.setModel(
-                mTelecomManager,
-                mTelecomManager.getSimCallManagers(),
+                mTelecomManager, mTelecomManager.getSimCallManagers(),
                 mTelecomManager.getSimCallManager(),
                 getString(R.string.wifi_calling_call_assistant_none));
     }
@@ -311,19 +315,103 @@
     }
 
     private void initAccountList() {
-        List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
-        if (sil == null) {
-            return;
+        // Obtain the list of phone accounts.
+        List<PhoneAccount> accounts = new ArrayList<>();
+        for (PhoneAccountHandle handle : mTelecomManager.getCallCapablePhoneAccounts()) {
+            PhoneAccount account = mTelecomManager.getPhoneAccount(handle);
+            if (account != null) {
+                accounts.add(account);
+            }
         }
-        for (SubscriptionInfo subscription : sil) {
-            CharSequence label = subscription.getDisplayName();
-            Intent intent = new Intent(TelecomManager.ACTION_SHOW_CALL_SETTINGS);
-            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            SubscriptionInfoHelper.addExtrasToIntent(intent, subscription);
 
+        // Sort the accounts according to how we want to display them.
+        Collections.sort(accounts, new Comparator<PhoneAccount>() {
+            @Override
+            public int compare(PhoneAccount account1, PhoneAccount account2) {
+                int retval = 0;
+
+                // SIM accounts go first
+                boolean isSim1 = (account1.getCapabilities() &
+                        PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0;
+                boolean isSim2 = (account2.getCapabilities() &
+                        PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0;
+                if (isSim1 != isSim2) {
+                    retval = isSim1 ? -1 : 1;
+                }
+
+                // Then order by package
+                if (retval == 0) {
+                    String pkg1 = account1.getAccountHandle().getComponentName().getPackageName();
+                    String pkg2 = account2.getAccountHandle().getComponentName().getPackageName();
+                    retval = pkg1.compareTo(pkg2);
+                }
+
+                // Finally, order by label
+                if (retval == 0) {
+                    String label1 = nullToEmpty(account1.getLabel().toString());
+                    String label2 = nullToEmpty(account2.getLabel().toString());
+                    retval = label1.compareTo(label2);
+                }
+
+                // Then by hashcode
+                if (retval == 0) {
+                    retval = account1.hashCode() - account2.hashCode();
+                }
+                return retval;
+            }
+        });
+
+        // Add an entry for each account.
+        for (PhoneAccount account : accounts) {
+            PhoneAccountHandle handle = account.getAccountHandle();
+            Intent intent = null;
+            boolean isSimAccount = false;
+
+            // SIM phone accounts use a different setting intent and are thus handled differently.
+            if ((PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION & account.getCapabilities()) != 0) {
+                isSimAccount = true;
+                SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(
+                        mTelephonyManager.getSubIdForPhoneAccount(account));
+
+                if (subInfo != null) {
+                    intent = new Intent(TelecomManager.ACTION_SHOW_CALL_SETTINGS);
+                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                    SubscriptionInfoHelper.addExtrasToIntent(intent, subInfo);
+                }
+            } else {
+                // Build the settings intent.
+                intent = new Intent(TelecomManager.ACTION_CONNECTION_SERVICE_CONFIGURE);
+                intent.setPackage(handle.getComponentName().getPackageName());
+                intent.addCategory(Intent.CATEGORY_DEFAULT);
+                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, handle);
+
+                // Check to see that the phone account package can handle the setting intent.
+                PackageManager pm = getActivity().getPackageManager();
+                List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
+                if (resolutions.size() == 0) {
+                    intent = null;  // set no intent if the package cannot handle it.
+                }
+            }
+
+            // Create the preference & add the label
             Preference accountPreference = new Preference(getActivity());
-            accountPreference.setTitle(label);
-            accountPreference.setIntent(intent);
+            accountPreference.setTitle(account.getLabel());
+
+            // Add an icon.
+            Drawable icon = account.createIconDrawable(getActivity());
+            if (isSimAccount && !mTelephonyManager.isMultiSimEnabled()) {
+                // If a device is not multi-SIM enabled, then it is unlikely the icon has any
+                // color to it.  In these cases, add a default gray tint.
+                icon.setTint(getResources().getColor(R.color.default_sim_icon_tint_color));
+                icon.setTintMode(PorterDuff.Mode.SRC_ATOP);
+            }
+            accountPreference.setIcon(icon);
+
+            // Add an intent to send the user to the account's settings.
+            if (intent != null) {
+                accountPreference.setIntent(intent);
+            }
+
             mAccountList.addPreference(accountPreference);
         }
     }
@@ -340,4 +428,13 @@
         }
         return null;
     }
+
+    private boolean shouldShowConnectionServiceList() {
+        return mTelephonyManager.isMultiSimEnabled() ||
+                mTelecomManager.getCallCapablePhoneAccounts().size() > 1;
+    }
+
+    private String nullToEmpty(String str) {
+        return str == null ? "" : str;
+    }
 }
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index 27349fe..f017836 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -622,7 +622,8 @@
         // In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
         // with settings UI. If we were called to explicitly configure voice mail then
         // we finish the settings activity here to come back to whatever the user was doing.
-        if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
+        final String action = getIntent() != null ? getIntent().getAction() : null;
+        if (ACTION_ADD_VOICEMAIL.equals(action)) {
             finish();
         }
     }
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
index e607d60..ec8e45e 100644
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
@@ -65,8 +65,8 @@
     private void handleCarrierConfigChange(Context context, Intent intent) {
         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            Log.w(TAG, "subscriptionId not provided in intent.");
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            Log.w(TAG, "Invalid subscriptionId or subscriptionId not provided in intent.");
             return;
         }
 
diff --git a/src/com/android/phone/vvm/omtp/sync/FetchVoicemailReceiver.java b/src/com/android/phone/vvm/omtp/sync/FetchVoicemailReceiver.java
index 66fed16..88d6983 100644
--- a/src/com/android/phone/vvm/omtp/sync/FetchVoicemailReceiver.java
+++ b/src/com/android/phone/vvm/omtp/sync/FetchVoicemailReceiver.java
@@ -85,6 +85,13 @@
                     }
                     final Account account = new Account(accountId,
                             OmtpVvmSyncAccountManager.ACCOUNT_TYPE);
+
+                    if (!OmtpVvmSyncAccountManager.getInstance(context)
+                            .isAccountRegistered(account)) {
+                        Log.w(TAG, "Account not registered - cannot retrieve message.");
+                        return;
+                    }
+
                     Executor executor = Executors.newCachedThreadPool();
                     executor.execute(new Runnable() {
                         @Override