Merge "Fix plus sign of country code prefixes can't show on CDMA MO call"
diff --git a/OWNERS b/OWNERS
index f190411..1d3173f 100644
--- a/OWNERS
+++ b/OWNERS
@@ -9,3 +9,4 @@
 mpq@google.com
 jminjie@google.com
 shuoq@google.com
+paulye@google.com
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index c48f5cb..0c4cffc 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -788,6 +788,9 @@
             int max = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
             mActiveSubInfos = new ArrayList<SubscriptionInfo>(max);
 
+            int currentTab = mTabHost != null ? mTabHost.getCurrentTab() : 0;
+            updatePhone(currentTab);
+            updateEnabledNetworksEntries();
             Log.i(LOG_TAG, "onCreate:-");
         }
 
@@ -1025,95 +1028,7 @@
                 updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
             } else {
                 prefSet.removePreference(mButtonPreferredNetworkMode);
-                final int phoneType = mPhone.getPhoneType();
-                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                    int lteForced = android.provider.Settings.Global.getInt(
-                            mPhone.getContext().getContentResolver(),
-                            android.provider.Settings.Global.LTE_SERVICE_FORCED + mPhone.getSubId(),
-                            0);
-
-                    if (isLteOnCdma) {
-                        if (lteForced == 0) {
-                            mButtonEnabledNetworks.setEntries(
-                                    R.array.enabled_networks_cdma_choices);
-                            mButtonEnabledNetworks.setEntryValues(
-                                    R.array.enabled_networks_cdma_values);
-                        } else {
-                            switch (settingsNetworkMode) {
-                                case Phone.NT_MODE_CDMA:
-                                case Phone.NT_MODE_CDMA_NO_EVDO:
-                                case Phone.NT_MODE_EVDO_NO_CDMA:
-                                    mButtonEnabledNetworks.setEntries(
-                                            R.array.enabled_networks_cdma_no_lte_choices);
-                                    mButtonEnabledNetworks.setEntryValues(
-                                            R.array.enabled_networks_cdma_no_lte_values);
-                                    break;
-                                case Phone.NT_MODE_GLOBAL:
-                                case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
-                                case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
-                                case Phone.NT_MODE_LTE_ONLY:
-                                    mButtonEnabledNetworks.setEntries(
-                                            R.array.enabled_networks_cdma_only_lte_choices);
-                                    mButtonEnabledNetworks.setEntryValues(
-                                            R.array.enabled_networks_cdma_only_lte_values);
-                                    break;
-                                default:
-                                    mButtonEnabledNetworks.setEntries(
-                                            R.array.enabled_networks_cdma_choices);
-                                    mButtonEnabledNetworks.setEntryValues(
-                                            R.array.enabled_networks_cdma_values);
-                                    break;
-                            }
-                        }
-                    }
-                    updateCdmaOptions(this, prefSet, mPhone);
-
-                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    if (isSupportTdscdma()) {
-                        mButtonEnabledNetworks.setEntries(
-                                R.array.enabled_networks_tdscdma_choices);
-                        mButtonEnabledNetworks.setEntryValues(
-                                R.array.enabled_networks_tdscdma_values);
-                    } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
-                            && !getResources().getBoolean(R.bool.config_enabled_lte)) {
-                        mButtonEnabledNetworks.setEntries(
-                                R.array.enabled_networks_except_gsm_lte_choices);
-                        mButtonEnabledNetworks.setEntryValues(
-                                R.array.enabled_networks_except_gsm_lte_values);
-                    } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
-                        int select = (mShow4GForLTE == true) ?
-                                R.array.enabled_networks_except_gsm_4g_choices
-                                : R.array.enabled_networks_except_gsm_choices;
-                        mButtonEnabledNetworks.setEntries(select);
-                        mButtonEnabledNetworks.setEntryValues(
-                                R.array.enabled_networks_except_gsm_values);
-                    } else if (!getResources().getBoolean(R.bool.config_enabled_lte)) {
-                        mButtonEnabledNetworks.setEntries(
-                                R.array.enabled_networks_except_lte_choices);
-                        mButtonEnabledNetworks.setEntryValues(
-                                R.array.enabled_networks_except_lte_values);
-                    } else if (mIsGlobalCdma) {
-                        mButtonEnabledNetworks.setEntries(
-                                R.array.enabled_networks_cdma_choices);
-                        mButtonEnabledNetworks.setEntryValues(
-                                R.array.enabled_networks_cdma_values);
-                    } else {
-                        int select = (mShow4GForLTE == true) ? R.array.enabled_networks_4g_choices
-                                : R.array.enabled_networks_choices;
-                        mButtonEnabledNetworks.setEntries(select);
-                        mButtonEnabledNetworks.setEntryValues(
-                                R.array.enabled_networks_values);
-                    }
-                    updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
-                } else {
-                    throw new IllegalStateException("Unexpected phone type: " + phoneType);
-                }
-                if (isWorldMode()) {
-                    mButtonEnabledNetworks.setEntries(
-                            R.array.preferred_network_mode_choices_world_mode);
-                    mButtonEnabledNetworks.setEntryValues(
-                            R.array.preferred_network_mode_values_world_mode);
-                }
+                updateEnabledNetworksEntries();
                 mButtonEnabledNetworks.setOnPreferenceChangeListener(this);
                 if (DBG) log("settingsNetworkMode: " + settingsNetworkMode);
             }
@@ -1214,6 +1129,107 @@
             }
         }
 
+        // Requires that mPhone is up to date
+        void updateEnabledNetworksEntries() {
+            final int phoneType = mPhone.getPhoneType();
+            final PersistableBundle carrierConfig =
+                    PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                final int lteForced = android.provider.Settings.Global.getInt(
+                        mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.LTE_SERVICE_FORCED + mPhone.getSubId(),
+                        0);
+                final boolean isLteOnCdma = mPhone.getLteOnCdmaMode()
+                        == PhoneConstants.LTE_ON_CDMA_TRUE;
+                final int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                        mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE + mPhone.getSubId(),
+                        preferredNetworkMode);
+                if (isLteOnCdma) {
+                    if (lteForced == 0) {
+                        mButtonEnabledNetworks.setEntries(
+                                R.array.enabled_networks_cdma_choices);
+                        mButtonEnabledNetworks.setEntryValues(
+                                R.array.enabled_networks_cdma_values);
+                    } else {
+                        switch (settingsNetworkMode) {
+                            case Phone.NT_MODE_CDMA:
+                            case Phone.NT_MODE_CDMA_NO_EVDO:
+                            case Phone.NT_MODE_EVDO_NO_CDMA:
+                                mButtonEnabledNetworks.setEntries(
+                                        R.array.enabled_networks_cdma_no_lte_choices);
+                                mButtonEnabledNetworks.setEntryValues(
+                                        R.array.enabled_networks_cdma_no_lte_values);
+                                break;
+                            case Phone.NT_MODE_GLOBAL:
+                            case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+                            case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                            case Phone.NT_MODE_LTE_ONLY:
+                                mButtonEnabledNetworks.setEntries(
+                                        R.array.enabled_networks_cdma_only_lte_choices);
+                                mButtonEnabledNetworks.setEntryValues(
+                                        R.array.enabled_networks_cdma_only_lte_values);
+                                break;
+                            default:
+                                mButtonEnabledNetworks.setEntries(
+                                        R.array.enabled_networks_cdma_choices);
+                                mButtonEnabledNetworks.setEntryValues(
+                                        R.array.enabled_networks_cdma_values);
+                                break;
+                        }
+                    }
+                }
+                updateCdmaOptions(this, getPreferenceScreen(), mPhone);
+
+            } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                if (isSupportTdscdma()) {
+                    mButtonEnabledNetworks.setEntries(
+                            R.array.enabled_networks_tdscdma_choices);
+                    mButtonEnabledNetworks.setEntryValues(
+                            R.array.enabled_networks_tdscdma_values);
+                } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)
+                        && !getResources().getBoolean(R.bool.config_enabled_lte)) {
+                    mButtonEnabledNetworks.setEntries(
+                            R.array.enabled_networks_except_gsm_lte_choices);
+                    mButtonEnabledNetworks.setEntryValues(
+                            R.array.enabled_networks_except_gsm_lte_values);
+                } else if (!carrierConfig.getBoolean(CarrierConfigManager.KEY_PREFER_2G_BOOL)) {
+                    int select = mShow4GForLTE
+                            ? R.array.enabled_networks_except_gsm_4g_choices
+                            : R.array.enabled_networks_except_gsm_choices;
+                    mButtonEnabledNetworks.setEntries(select);
+                    mButtonEnabledNetworks.setEntryValues(
+                            R.array.enabled_networks_except_gsm_values);
+                } else if (!getResources().getBoolean(R.bool.config_enabled_lte)) {
+                    mButtonEnabledNetworks.setEntries(
+                            R.array.enabled_networks_except_lte_choices);
+                    mButtonEnabledNetworks.setEntryValues(
+                            R.array.enabled_networks_except_lte_values);
+                } else if (mIsGlobalCdma) {
+                    mButtonEnabledNetworks.setEntries(
+                            R.array.enabled_networks_cdma_choices);
+                    mButtonEnabledNetworks.setEntryValues(
+                            R.array.enabled_networks_cdma_values);
+                } else {
+                    int select = mShow4GForLTE ? R.array.enabled_networks_4g_choices
+                            : R.array.enabled_networks_choices;
+                    mButtonEnabledNetworks.setEntries(select);
+                    mButtonEnabledNetworks.setEntryValues(
+                            R.array.enabled_networks_values);
+                }
+                updateGsmUmtsOptions(this, getPreferenceScreen(), mPhone.getSubId(),
+                        mNetworkQueryService);
+            } else {
+                throw new IllegalStateException("Unexpected phone type: " + phoneType);
+            }
+            if (isWorldMode()) {
+                mButtonEnabledNetworks.setEntries(
+                        R.array.preferred_network_mode_choices_world_mode);
+                mButtonEnabledNetworks.setEntryValues(
+                        R.array.preferred_network_mode_values_world_mode);
+            }
+        }
+
         @Override
         public void onPause() {
             super.onPause();
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 444eae0..a97c4b3 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -4987,6 +4987,54 @@
         }
     }
 
+    /**
+     * Checks if data roaming is enabled on the subscription with id {@code subId}.
+     *
+     * <p>Requires one of the following permissions:
+     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
+     * privileges.
+     *
+     * @param subId subscription id
+     * @return {@code true} if data roaming is enabled on this subscription, otherwise return
+     * {@code false}.
+     */
+    @Override
+    public boolean isDataRoamingEnabled(int subId) {
+        try {
+            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
+                    null);
+        } catch (Exception e) {
+            TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
+                    mApp, subId, "isDataRoamingEnabled");
+        }
+
+        Phone phone = getPhone(subId);
+        return phone != null ? phone.getDataRoamingEnabled() : false;
+    }
+
+
+    /**
+     * Enables/Disables the data roaming on the subscription with id {@code subId}.
+     *
+     * <p> Requires permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
+     * privileges.
+     *
+     * @param subId subscription id
+     * @param isEnabled {@code true} means enable, {@code false} means disable.
+     */
+    @Override
+    public void setDataRoamingEnabled(int subId, boolean isEnabled) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setDataRoamingEbaled");
+
+        Phone phone = getPhone(subId);
+        if (phone != null) {
+            phone.setDataRoamingEnabled(isEnabled);
+        }
+    }
+
     @Override
     public UiccSlotInfo[] getUiccSlotsInfo() {
         enforceReadPrivilegedPermission();
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 6c8dcaa..642af85 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -107,9 +107,31 @@
         }
 
         /**
+         * Trigger re-registration of this account.
+         */
+        public void reRegisterPstnPhoneAccount() {
+            PhoneAccount newAccount = buildPstnPhoneAccount(mIsEmergency, mIsDummy);
+            if (!newAccount.equals(mAccount)) {
+                Log.i(this, "reRegisterPstnPhoneAccount: subId: " + getSubId()
+                        + " - re-register due to account change.");
+                mTelecomManager.registerPhoneAccount(newAccount);
+                mAccount = newAccount;
+            } else {
+                Log.i(this, "reRegisterPstnPhoneAccount: subId: " + getSubId() + " - no change");
+            }
+        }
+
+        private PhoneAccount registerPstnPhoneAccount(boolean isEmergency, boolean isDummyAccount) {
+            PhoneAccount account = buildPstnPhoneAccount(mIsEmergency, mIsDummy);
+            // Register with Telecom and put into the account entry.
+            mTelecomManager.registerPhoneAccount(account);
+            return account;
+        }
+
+        /**
          * Registers the specified account with Telecom as a PhoneAccountHandle.
          */
-        private PhoneAccount registerPstnPhoneAccount(boolean isEmergency, boolean isDummyAccount) {
+        private PhoneAccount buildPstnPhoneAccount(boolean isEmergency, boolean isDummyAccount) {
             String dummyPrefix = isDummyAccount ? "Dummy " : "";
 
             // Build the Phone account handle.
@@ -312,9 +334,6 @@
                     .setGroupId(groupId)
                     .build();
 
-            // Register with Telecom and put into the account entry.
-            mTelecomManager.registerPhoneAccount(account);
-
             return account;
         }
 
@@ -322,6 +341,10 @@
             return mAccount != null ? mAccount.getAccountHandle() : null;
         }
 
+        public int getSubId() {
+            return mPhone.getSubId();
+        }
+
         /**
          * Determines from carrier configuration whether pausing of IMS video calls is supported.
          *
@@ -579,19 +602,27 @@
         }
     };
 
-    private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            Log.i(this, "User changed, re-registering phone accounts.");
+            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+                Log.i(this, "User changed, re-registering phone accounts.");
 
-            int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-            UserHandle currentUserHandle = new UserHandle(userHandleId);
-            mIsPrimaryUser = UserManager.get(mContext).getPrimaryUser().getUserHandle()
-                    .equals(currentUserHandle);
+                int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                UserHandle currentUserHandle = new UserHandle(userHandleId);
+                mIsPrimaryUser = UserManager.get(mContext).getPrimaryUser().getUserHandle()
+                        .equals(currentUserHandle);
 
-            // Any time the user changes, re-register the accounts.
-            tearDownAccounts();
-            setupAccounts();
+                // Any time the user changes, re-register the accounts.
+                tearDownAccounts();
+                setupAccounts();
+            } else if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(
+                    intent.getAction())) {
+                Log.i(this, "Carrier-config changed, checking for phone account updates.");
+                int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+                handleCarrierConfigChange(subId);
+            }
         }
     };
 
@@ -814,8 +845,10 @@
 
         // Listen for user switches.  When the user switches, we need to ensure that if the current
         // use is not the primary user we disable video calling.
-        mContext.registerReceiver(mUserSwitchedReceiver,
-                new IntentFilter(Intent.ACTION_USER_SWITCHED));
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_SWITCHED);
+        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        mContext.registerReceiver(mReceiver, filter);
 
         // Listen to the RTT system setting so that we update it when the user flips it.
         ContentObserver rttUiSettingObserver = new ContentObserver(
@@ -951,4 +984,27 @@
             mAccounts.clear();
         }
     }
+
+    /**
+     * Handles changes to the carrier configuration which may impact a phone account.  There are
+     * some extras defined in the {@link PhoneAccount} which are based on carrier config options.
+     * Only checking for carrier config changes when the subscription is configured runs the risk of
+     * missing carrier config changes which happen later.
+     * @param subId The subid the carrier config changed for, if applicable.  Will be
+     *              {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if not specified.
+     */
+    private void handleCarrierConfigChange(int subId) {
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return;
+        }
+        synchronized (mAccountsLock) {
+            for (AccountEntry entry : mAccounts) {
+                if (entry.getSubId() == subId) {
+                    Log.d(this, "handleCarrierConfigChange: subId=%d, accountSubId=%d", subId,
+                            entry.getSubId());
+                    entry.reRegisterPstnPhoneAccount();
+                }
+            }
+        }
+    }
 }