Merge "Enforce READ_PHONE_STATE for getCallState APIs" into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 28d88f3..d7181dd 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -135,6 +135,8 @@
     <uses-permission android:name="android.permission.VIBRATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
     <uses-permission android:name="android.permission.REORDER_TASKS" />
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
@@ -586,16 +588,6 @@
             </intent-filter>
         </receiver>
 
-        <activity android:name="com.android.services.telephony.sip.SipPhoneAccountSettingsActivity"
-                android:theme="@android:style/Theme.NoDisplay"
-                android:exported="true"
-                android:excludeFromRecents="true">
-            <intent-filter>
-                <action android:name="android.telecom.action.CONFIGURE_PHONE_ACCOUNT" />
-                <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/values/strings.xml b/res/values/strings.xml
index 4df6a52..46eaaaf 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -644,6 +644,13 @@
     <string name="limited_sim_function_with_phone_num_notification_message"><xliff:g id="carrier_name">%1$s</xliff:g> calls and data services may be blocked while using <xliff:g id="phone_number">%2$s</xliff:g>.</string>
     <!-- Notification message for limited sim function during dual sim [CHAR LIMIT=80]-->
     <string name="limited_sim_function_notification_message"><xliff:g id="carrier_name">%1$s</xliff:g> calls and data services may be blocked while using another SIM.</string>
+    <!-- Notification title for SIP accounts removed -->
+    <string name="sip_accounts_removed_notification_title">Deprecated SIP accounts found and removed</string>
+    <!-- Notification message for SIP accoutns removed -->
+    <string name="sip_accounts_removed_notification_message">
+        SIP calling is no longer supported by Android platform.\nYour existing SIP accounts <xliff:g id="removed_sip_accounts">%s</xliff:g> have been removed.\nPlease confirm your default calling account setting.
+    </string>
+    <string name="sip_accounts_removed_notification_action">Go to settings</string>
     <!-- Mobile network settings screen, data usage setting check box name -->
     <string name="data_usage_title">App data usage</string>
     <!-- Summary about how much data has been used in a date range [CHAR LIMIT=100] -->
@@ -2180,4 +2187,7 @@
     <!-- name of the notification that pops up during
     a phone call when there is bad call quality -->
     <string name="call_quality_notification_name">Call Quality Notification</string>
+    <!-- Telephony notification channel name for a channel containing SIP accounts removed
+     notificatios -->
+    <string name="notification_channel_sip_account">Deprecated SIP accounts</string>
 </resources>
diff --git a/res/xml/phone_account_settings.xml b/res/xml/phone_account_settings.xml
index a243a65..8722761 100644
--- a/res/xml/phone_account_settings.xml
+++ b/res/xml/phone_account_settings.xml
@@ -55,34 +55,4 @@
 
     </PreferenceCategory>
 
-    <PreferenceCategory
-        android:key="phone_accounts_sip_settings_category_key"
-        android:title="@string/sip_settings"
-        android:persistent="false">
-
-        <PreferenceScreen
-            android:title="@string/sip_accounts"
-            android:persistent="false">
-
-            <intent android:action="android.intent.action.MAIN"
-                android:targetPackage="com.android.phone"
-                android:targetClass="com.android.services.telephony.sip.SipSettings" />
-
-        </PreferenceScreen>
-
-        <ListPreference
-            android:key="use_sip_calling_options_key"
-            android:title="@string/sip_call_options_title"
-            android:persistent="true"
-            android:entries="@array/sip_call_options_entries"
-            android:entryValues="@array/sip_call_options_values"/>
-
-        <SwitchPreference
-            android:key="sip_receive_calls_key"
-            android:title="@string/sip_receive_calls"
-            android:summary="@string/sip_receive_calls_summary"
-            android:persistent="true"/>
-
-    </PreferenceCategory>
-
 </PreferenceScreen>
diff --git a/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java b/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
index 1cf7f4b..2845dac 100644
--- a/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
+++ b/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
@@ -16,8 +16,12 @@
 
 package com.android.services.telephony.sip;
 
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.Context;
-import android.net.sip.SipException;
+import android.content.Intent;
 import android.net.sip.SipManager;
 import android.net.sip.SipProfile;
 import android.telecom.PhoneAccount;
@@ -25,9 +29,13 @@
 import android.telecom.TelecomManager;
 import android.util.Log;
 
+import com.android.phone.R;
+
+import java.io.IOException;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
 
 /**
  * Manages the {@link PhoneAccount} entries for SIP calling.
@@ -45,41 +53,6 @@
         }
 
         /**
-         * Starts the SIP service associated with the SIP profile.
-         *
-         * @param sipManager The SIP manager.
-         * @param context The context.
-         * @param isReceivingCalls {@code True} if the sip service is being started to make and
-         *          receive calls.  {@code False} if the sip service is being started only for
-         *          outgoing calls.
-         * @return {@code True} if the service started successfully.
-         */
-        boolean startSipService(SipManager sipManager, Context context, boolean isReceivingCalls) {
-            if (VERBOSE) log("startSipService, profile: " + mProfile);
-            try {
-                // Stop the Sip service for the profile if it is already running.  This is important
-                // if we are changing the state of the "receive calls" option.
-                sipManager.close(mProfile.getUriString());
-
-                // Start the sip service for the profile.
-                if (isReceivingCalls) {
-                    sipManager.open(
-                            mProfile,
-                            SipUtil.createIncomingCallPendingIntent(context,
-                                    mProfile.getProfileName()),
-                            null);
-                } else {
-                    sipManager.open(mProfile);
-                }
-                return true;
-            } catch (SipException e) {
-                log("startSipService, profile: " + mProfile.getProfileName() +
-                        ", exception: " + e);
-            }
-            return false;
-        }
-
-        /**
          * Stops the SIP service associated with the SIP profile.  The {@code SipAccountRegistry} is
          * informed when the service has been stopped via an intent which triggers
          * {@link SipAccountRegistry#removeSipProfile(String)}.
@@ -102,9 +75,16 @@
     private static final String PREFIX = "[SipAccountRegistry] ";
     private static final boolean VERBOSE = false; /* STOP SHIP if true */
     private static final SipAccountRegistry INSTANCE = new SipAccountRegistry();
+    private static final String NOTIFICATION_TAG = SipAccountRegistry.class.getSimpleName();
+    private static final int SIP_ACCOUNTS_REMOVED_NOTIFICATION_ID = 1;
+
+    private static final String CHANNEL_ID_SIP_ACCOUNTS_REMOVED = "sipAccountsRemoved";
 
     private final List<AccountEntry> mAccounts = new CopyOnWriteArrayList<>();
 
+    private NotificationChannel mNotificationChannel;
+    private NotificationManager mNm;
+
     private SipAccountRegistry() {}
 
     public static SipAccountRegistry getInstance() {
@@ -115,8 +95,20 @@
      * Sets up the Account registry and performs any upgrade operations before it is used.
      */
     public void setup(Context context) {
+        setupNotificationChannel(context);
         verifyAndPurgeInvalidPhoneAccounts(context);
-        startSipProfilesAsync(context, (String) null, false);
+        startSipProfilesAsync(context);
+    }
+
+    private void setupNotificationChannel(Context context) {
+        mNotificationChannel = new NotificationChannel(
+                CHANNEL_ID_SIP_ACCOUNTS_REMOVED,
+                context.getText(R.string.notification_channel_sip_account),
+                NotificationManager.IMPORTANCE_HIGH);
+        mNm = context.getSystemService(NotificationManager.class);
+        if (mNm != null) {
+            mNm.createNotificationChannel(mNotificationChannel);
+        }
     }
 
     /**
@@ -149,8 +141,8 @@
      * @param sipProfileName The name of the {@link SipProfile} to start, or {@code null} for all.
      * @param enableProfile Sip account should be enabled
      */
-    void startSipService(Context context, String sipProfileName, boolean enableProfile) {
-        startSipProfilesAsync(context, sipProfileName, enableProfile);
+    void startSipService(Context context, String sipProfileName, boolean enabledProfile) {
+        startSipProfilesAsync(context);
     }
 
     /**
@@ -193,33 +185,20 @@
     }
 
     /**
-     * Causes the SIP service to be restarted for all {@link SipProfile}s.  For example, if the user
-     * toggles the "receive calls" option for SIP, this method handles restarting the SIP services
-     * in the new mode.
-     *
-     * @param context The context.
-     */
-    public void restartSipService(Context context) {
-        startSipProfiles(context, null, false);
-    }
-
-    /**
      * Performs an asynchronous call to
      * {@link SipAccountRegistry#startSipProfiles(android.content.Context, String)}, starting the
      * specified SIP profile and registering its {@link android.telecom.PhoneAccount}.
      *
      * @param context The context.
-     * @param sipProfileName Name of the SIP profile.
-     * @param enableProfile Sip account should be enabled.
      */
     private void startSipProfilesAsync(
-            final Context context, final String sipProfileName, final boolean enableProfile) {
+            final Context context) {
         if (VERBOSE) log("startSipProfiles, start auto registration");
 
         new Thread(new Runnable() {
             @Override
             public void run() {
-                startSipProfiles(context, sipProfileName, enableProfile);
+                startSipProfiles(context);
             }}
         ).start();
     }
@@ -230,48 +209,54 @@
      * register the associated SIP account.
      *
      * @param context The context.
-     * @param sipProfileName A specific SIP profile Name to start, or {@code null} to start all.
-     * @param enableProfile Sip account should be enabled.
      */
-    private void startSipProfiles(Context context, String sipProfileName, boolean enableProfile) {
-        final SipPreferences sipPreferences = new SipPreferences(context);
-        boolean isReceivingCalls = sipPreferences.isReceivingCallsEnabled();
-        TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
-        SipManager sipManager = SipManager.newInstance(context);
+    private void startSipProfiles(Context context) {
         SipProfileDb profileDb = new SipProfileDb(context);
         List<SipProfile> sipProfileList = profileDb.retrieveSipProfileList();
 
-        for (SipProfile profile : sipProfileList) {
-            // Register a PhoneAccount for the profile and optionally enable the primary
-            // profile.
-            if (sipProfileName == null || sipProfileName.equals(profile.getProfileName())) {
-                PhoneAccount phoneAccount = SipUtil.createPhoneAccount(context, profile);
-                telecomManager.registerPhoneAccount(phoneAccount);
-                if (enableProfile) {
-                    telecomManager.enablePhoneAccount(phoneAccount.getAccountHandle(), true);
+        // If there're SIP profiles existing in DB, display a notification and delete all these
+        // profiles.
+        if (!sipProfileList.isEmpty()) {
+            for (SipProfile profile : sipProfileList) {
+                stopSipService(context, profile.getProfileName());
+                removeSipProfile(profile.getProfileName());
+                try {
+                    profileDb.deleteProfile(profile);
+                } catch (IOException e) {
+                    // Ignore
                 }
-                startSipServiceForProfile(profile, sipManager, context, isReceivingCalls);
             }
+            sendSipAccountsRemovedNotification(context, sipProfileList);
         }
     }
 
-    /**
-     * Starts the SIP service for a sip profile and saves a new {@code AccountEntry} in the
-     * registry.
-     *
-     * @param profile The {@link SipProfile} to start.
-     * @param sipManager The SIP manager.
-     * @param context The context.
-     * @param isReceivingCalls {@code True} if the profile should be started such that it can
-     *      receive incoming calls.
-     */
-    private void startSipServiceForProfile(SipProfile profile, SipManager sipManager,
-            Context context, boolean isReceivingCalls) {
-        removeSipProfile(profile.getUriString());
+    private void sendSipAccountsRemovedNotification(Context context, List<SipProfile> profiles) {
+        String sipAccounts = profiles.stream().map(p -> p.getProfileName())
+                .collect(Collectors.joining(","));
 
-        AccountEntry entry = new AccountEntry(profile);
-        if (entry.startSipService(sipManager, context, isReceivingCalls)) {
-            mAccounts.add(entry);
+        Intent intent = new Intent(TelecomManager.ACTION_CHANGE_PHONE_ACCOUNTS);
+        intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+
+        Notification.Action action = new Notification.Action.Builder(R.drawable.ic_sim_card,
+                context.getString(R.string.sip_accounts_removed_notification_action),
+                pendingIntent).build();
+        Notification.Builder builder = new Notification.Builder(context)
+                .setSmallIcon(R.drawable.ic_sim_card)
+                .setChannelId(CHANNEL_ID_SIP_ACCOUNTS_REMOVED)
+                .setContentTitle(context.getText(R.string.sip_accounts_removed_notification_title))
+                .setStyle(new Notification.BigTextStyle()
+                .bigText(context.getString(
+                        R.string.sip_accounts_removed_notification_message,
+                        sipAccounts)))
+                .setAutoCancel(true)
+                .addAction(action);
+        Notification notification = builder.build();
+        if (mNm != null) {
+            mNm.notify(NOTIFICATION_TAG, SIP_ACCOUNTS_REMOVED_NOTIFICATION_ID,
+                    notification);
+        } else {
+            log("NotificationManager is null when send the notification of removed SIP accounts");
         }
     }
 
diff --git a/sip/src/com/android/services/telephony/sip/SipPhoneAccountSettingsActivity.java b/sip/src/com/android/services/telephony/sip/SipPhoneAccountSettingsActivity.java
deleted file mode 100644
index a6f6381..0000000
--- a/sip/src/com/android/services/telephony/sip/SipPhoneAccountSettingsActivity.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 profileName = SipUtil.getSipProfileNameFromPhoneAccount(accountHandle);
-                SipProfile profile = profileDb.retrieveSipProfileFromName(profileName);
-                if (profile != null) {
-                    Intent settingsIntent = new Intent(this, SipEditor.class);
-                    settingsIntent.putExtra(SipSettings.KEY_SIP_PROFILE, (Parcelable) profile);
-                    startActivity(settingsIntent);
-                }
-            }
-        }
-
-        finish();
-    }
-}
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 3811a77..224a1f9 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -6,14 +6,11 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Icon;
-import android.net.sip.SipManager;
 import android.os.Bundle;
 import android.os.UserManager;
-import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceFragment;
-import android.preference.SwitchPreference;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -28,9 +25,6 @@
 import com.android.phone.PhoneUtils;
 import com.android.phone.R;
 import com.android.phone.SubscriptionInfoHelper;
-import com.android.services.telephony.sip.SipAccountRegistry;
-import com.android.services.telephony.sip.SipPreferences;
-import com.android.services.telephony.sip.SipUtil;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -48,11 +42,6 @@
 
     private static final String ALL_CALLING_ACCOUNTS_KEY = "phone_accounts_all_calling_accounts";
 
-    private static final String SIP_SETTINGS_CATEGORY_PREF_KEY =
-            "phone_accounts_sip_settings_category_key";
-    private static final String USE_SIP_PREF_KEY = "use_sip_calling_options_key";
-    private static final String SIP_RECEIVE_CALLS_PREF_KEY = "sip_receive_calls_key";
-
     private static final String MAKE_AND_RECEIVE_CALLS_CATEGORY_KEY =
             "make_and_receive_calls_settings_category_key";
     private static final String DEFAULT_OUTGOING_ACCOUNT_KEY = "default_outgoing_account";
@@ -84,10 +73,6 @@
     private PreferenceCategory mMakeAndReceiveCallsCategory;
     private boolean mMakeAndReceiveCallsCategoryPresent;
 
-    private ListPreference mUseSipCalling;
-    private SwitchPreference mSipReceiveCallsPreference;
-    private SipPreferences mSipPreferences;
-
     private final SubscriptionManager.OnSubscriptionsChangedListener
             mOnSubscriptionsChangeListener =
             new SubscriptionManager.OnSubscriptionsChangedListener() {
@@ -154,39 +139,6 @@
         updateAccounts();
         updateMakeCallsOptions();
 
-        if (isPrimaryUser() && SipUtil.isVoipSupported(getActivity())) {
-            mSipPreferences = new SipPreferences(getActivity());
-
-            mUseSipCalling = (ListPreference)
-                    getPreferenceScreen().findPreference(USE_SIP_PREF_KEY);
-            mUseSipCalling.setEntries(!SipManager.isSipWifiOnly(getActivity())
-                    ? R.array.sip_call_options_wifi_only_entries
-                    : R.array.sip_call_options_entries);
-            mUseSipCalling.setOnPreferenceChangeListener(this);
-
-            int optionsValueIndex =
-                    mUseSipCalling.findIndexOfValue(mSipPreferences.getSipCallOption());
-            if (optionsValueIndex == -1) {
-                // If the option is invalid (eg. deprecated value), default to SIP_ADDRESS_ONLY.
-                mSipPreferences.setSipCallOption(
-                        getResources().getString(R.string.sip_address_only));
-                optionsValueIndex =
-                        mUseSipCalling.findIndexOfValue(mSipPreferences.getSipCallOption());
-            }
-            mUseSipCalling.setValueIndex(optionsValueIndex);
-            mUseSipCalling.setSummary(mUseSipCalling.getEntry());
-
-            mSipReceiveCallsPreference = (SwitchPreference)
-                    getPreferenceScreen().findPreference(SIP_RECEIVE_CALLS_PREF_KEY);
-            mSipReceiveCallsPreference.setEnabled(SipUtil.isPhoneIdle(getActivity()));
-            mSipReceiveCallsPreference.setChecked(
-                    mSipPreferences.isReceivingCallsEnabled());
-            mSipReceiveCallsPreference.setOnPreferenceChangeListener(this);
-        } else {
-            getPreferenceScreen().removePreference(
-                    getPreferenceScreen().findPreference(SIP_SETTINGS_CATEGORY_PREF_KEY));
-        }
-
         SubscriptionManager.from(getActivity()).addOnSubscriptionsChangedListener(
                 mOnSubscriptionsChangeListener);
     }
@@ -207,21 +159,6 @@
      */
     @Override
     public boolean onPreferenceChange(Preference pref, Object objValue) {
-        if (pref == mUseSipCalling) {
-            String option = objValue.toString();
-            mSipPreferences.setSipCallOption(option);
-            mUseSipCalling.setValueIndex(mUseSipCalling.findIndexOfValue(option));
-            mUseSipCalling.setSummary(mUseSipCalling.getEntry());
-            return true;
-        } else if (pref == mSipReceiveCallsPreference) {
-            final boolean isEnabled = !mSipReceiveCallsPreference.isChecked();
-            new Thread(new Runnable() {
-                public void run() {
-                    handleSipReceiveCallsOption(isEnabled);
-                }
-            }).start();
-            return true;
-        }
         return false;
     }
 
@@ -256,22 +193,6 @@
     @Override
     public void onAccountChanged(AccountSelectionPreference pref) {}
 
-    private synchronized void handleSipReceiveCallsOption(boolean isEnabled) {
-        Context context = getActivity();
-        if (context == null) {
-            // Return if the fragment is detached from parent activity before executed by thread.
-            return;
-        }
-
-        mSipPreferences.setReceivingCallsEnabled(isEnabled);
-
-        SipUtil.useSipToReceiveIncomingCalls(context, isEnabled);
-
-        // Restart all Sip services to ensure we reflect whether we are receiving calls.
-        SipAccountRegistry sipAccountRegistry = SipAccountRegistry.getInstance();
-        sipAccountRegistry.restartSipService(context);
-    }
-
     /**
      * Queries the telcomm manager to update the default outgoing account selection preference
      * with the list of outgoing accounts and the current default outgoing account.
@@ -409,32 +330,24 @@
             mAccountList.removeAll();
             List<PhoneAccountHandle> allNonSimAccounts =
                     getCallingAccounts(false /* includeSims */, true /* includeDisabled */);
-            // Check to see if we should show the entire section at all.
-            if (shouldShowConnectionServiceList(allNonSimAccounts)) {
-                List<PhoneAccountHandle> enabledAccounts =
-                        getCallingAccounts(true /* includeSims */, false /* includeDisabled */);
-                // Initialize the account list with the set of enabled & SIM accounts.
-                initAccountList(enabledAccounts);
 
-                // Only show the 'Make Calls With..." option if there are multiple accounts.
-                if (enabledAccounts.size() > 1) {
-                    mMakeAndReceiveCallsCategory.addPreference(mDefaultOutgoingAccount);
-                    mMakeAndReceiveCallsCategoryPresent = true;
-                    mDefaultOutgoingAccount.setListener(this);
-                    updateDefaultOutgoingAccountsModel();
-                } else {
-                    mMakeAndReceiveCallsCategory.removePreference(mDefaultOutgoingAccount);
-                }
+            List<PhoneAccountHandle> enabledAccounts =
+                    getCallingAccounts(true /* includeSims */, false /* includeDisabled */);
+            // Initialize the account list with the set of enabled & SIM accounts.
+            initAccountList(enabledAccounts);
 
-                // If there are no third party (nonSim) accounts,
-                // then don't show enable/disable dialog.
-                if (!allNonSimAccounts.isEmpty()) {
-                    mAccountList.addPreference(mAllCallingAccounts);
-                } else {
-                    mAccountList.removePreference(mAllCallingAccounts);
-                }
+            // Always show the 'Make Calls With..." option
+            mMakeAndReceiveCallsCategory.addPreference(mDefaultOutgoingAccount);
+            mMakeAndReceiveCallsCategoryPresent = true;
+            mDefaultOutgoingAccount.setListener(this);
+            updateDefaultOutgoingAccountsModel();
+
+            // If there are no third party (nonSim) accounts,
+            // then don't show enable/disable dialog.
+            if (!allNonSimAccounts.isEmpty()) {
+                mAccountList.addPreference(mAllCallingAccounts);
             } else {
-                getPreferenceScreen().removePreference(mAccountList);
+                mAccountList.removePreference(mAllCallingAccounts);
             }
         }
     }
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index e684c7d..f7e2991 100755
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -1428,7 +1428,7 @@
 
         newProperties = changeBitmask(newProperties, PROPERTY_HIGH_DEF_AUDIO,
                 hasHighDefAudioProperty());
-        newProperties = changeBitmask(newProperties, PROPERTY_WIFI, isWifi());
+        newProperties = changeBitmask(newProperties, PROPERTY_WIFI, isWifi() && !isCrossSimCall());
         newProperties = changeBitmask(newProperties, PROPERTY_IS_EXTERNAL_CALL,
                 isExternalConnection());
         newProperties = changeBitmask(newProperties, PROPERTY_HAS_CDMA_VOICE_PRIVACY,
@@ -1501,6 +1501,17 @@
         // Subclass can override this to do cleanup.
     }
 
+    public void registerForCallEvents(Phone phone) {
+        phone.registerForPreciseCallStateChanged(mHandler, MSG_PRECISE_CALL_STATE_CHANGED, null);
+        phone.registerForHandoverStateChanged(mHandler, MSG_HANDOVER_STATE_CHANGED, null);
+        phone.registerForRedialConnectionChanged(mHandler, MSG_REDIAL_CONNECTION_CHANGED, null);
+        phone.registerForRingbackTone(mHandler, MSG_RINGBACK_TONE, null);
+        phone.registerForSuppServiceNotification(mHandler, MSG_SUPP_SERVICE_NOTIFY, null);
+        phone.registerForOnHoldTone(mHandler, MSG_ON_HOLD_TONE, null);
+        phone.registerForInCallVoicePrivacyOn(mHandler, MSG_CDMA_VOICE_PRIVACY_ON, null);
+        phone.registerForInCallVoicePrivacyOff(mHandler, MSG_CDMA_VOICE_PRIVACY_OFF, null);
+    }
+
     void setOriginalConnection(com.android.internal.telephony.Connection originalConnection) {
         Log.v(this, "new TelephonyConnection, originalConnection: " + originalConnection);
         if (mOriginalConnection != null && originalConnection != null
@@ -1517,17 +1528,8 @@
         mOriginalConnectionExtras.clear();
         mOriginalConnection = originalConnection;
         mOriginalConnection.setTelecomCallId(getTelecomCallId());
-        getPhone().registerForPreciseCallStateChanged(
-                mHandler, MSG_PRECISE_CALL_STATE_CHANGED, null);
-        getPhone().registerForHandoverStateChanged(
-                mHandler, MSG_HANDOVER_STATE_CHANGED, null);
-        getPhone().registerForRedialConnectionChanged(
-                mHandler, MSG_REDIAL_CONNECTION_CHANGED, null);
-        getPhone().registerForRingbackTone(mHandler, MSG_RINGBACK_TONE, null);
-        getPhone().registerForSuppServiceNotification(mHandler, MSG_SUPP_SERVICE_NOTIFY, null);
-        getPhone().registerForOnHoldTone(mHandler, MSG_ON_HOLD_TONE, null);
-        getPhone().registerForInCallVoicePrivacyOn(mHandler, MSG_CDMA_VOICE_PRIVACY_ON, null);
-        getPhone().registerForInCallVoicePrivacyOff(mHandler, MSG_CDMA_VOICE_PRIVACY_OFF, null);
+        registerForCallEvents(getPhone());
+
         mOriginalConnection.addPostDialListener(mPostDialListener);
         mOriginalConnection.addListener(mOriginalConnectionListener);
 
@@ -2046,15 +2048,7 @@
     void clearOriginalConnection() {
         if (mOriginalConnection != null) {
             if (getPhone() != null) {
-                getPhone().unregisterForPreciseCallStateChanged(mHandler);
-                getPhone().unregisterForRingbackTone(mHandler);
-                getPhone().unregisterForHandoverStateChanged(mHandler);
-                getPhone().unregisterForRedialConnectionChanged(mHandler);
-                getPhone().unregisterForDisconnect(mHandler);
-                getPhone().unregisterForSuppServiceNotification(mHandler);
-                getPhone().unregisterForOnHoldTone(mHandler);
-                getPhone().unregisterForInCallVoicePrivacyOn(mHandler);
-                getPhone().unregisterForInCallVoicePrivacyOff(mHandler);
+                unregisterForCallEvents(getPhone());
             }
             mOriginalConnection.removePostDialListener(mPostDialListener);
             mOriginalConnection.removeListener(mOriginalConnectionListener);
@@ -2062,6 +2056,18 @@
         }
     }
 
+    public void unregisterForCallEvents(Phone phone) {
+        phone.unregisterForPreciseCallStateChanged(mHandler);
+        phone.unregisterForRingbackTone(mHandler);
+        phone.unregisterForHandoverStateChanged(mHandler);
+        phone.unregisterForRedialConnectionChanged(mHandler);
+        phone.unregisterForDisconnect(mHandler);
+        phone.unregisterForSuppServiceNotification(mHandler);
+        phone.unregisterForOnHoldTone(mHandler);
+        phone.unregisterForInCallVoicePrivacyOn(mHandler);
+        phone.unregisterForInCallVoicePrivacyOff(mHandler);
+    }
+
     protected void hangup(int telephonyDisconnectCode) {
         if (mOriginalConnection != null) {
             mHangupDisconnectCause = telephonyDisconnectCode;
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 0803178..bc39ffc 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1728,7 +1728,7 @@
                     });
         }
 
-        com.android.internal.telephony.Connection originalConnection = null;
+        final com.android.internal.telephony.Connection originalConnection;
         try {
             if (phone != null) {
                 EmergencyNumber emergencyNumber =
@@ -1770,14 +1770,18 @@
                         }
                     }
                 }
+                connection.registerForCallEvents(phone);
                 originalConnection = phone.dial(number, new ImsPhone.ImsDialArgs.Builder()
                         .setVideoState(videoState)
                         .setIntentExtras(extras)
                         .setRttTextStream(connection.getRttTextStream())
                         .build());
+            } else {
+                originalConnection = null;
             }
         } catch (CallStateException e) {
             Log.e(this, e, "placeOutgoingConnection, phone.dial exception: " + e);
+            connection.unregisterForCallEvents(phone);
             handleCallStateException(e, connection, phone);
             return;
         }
@@ -1800,12 +1804,17 @@
                 startActivity(intent);
             }
             Log.d(this, "placeOutgoingConnection, phone.dial returned null");
+            connection.unregisterForCallEvents(phone);
             connection.setTelephonyConnectionDisconnected(
                     mDisconnectCauseFactory.toTelecomDisconnectCause(telephonyDisconnectCause,
                             "Connection is null", phone.getPhoneId()));
             connection.close();
         } else {
-            connection.setOriginalConnection(originalConnection);
+            getMainThreadHandler().post(() -> {
+                if (connection.getOriginalConnection() == null) {
+                    connection.setOriginalConnection(originalConnection);
+                }
+            });
         }
     }
 
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index 9d712d3..26dff9a 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -25,6 +25,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.PersistableBundle;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
@@ -150,6 +151,11 @@
         return null;
     }
 
+    @Override
+    public Handler getMainThreadHandler() {
+        return new Handler(Looper.getMainLooper());
+    }
+
     /**
      * @return CarrierConfig PersistableBundle for the subscription specified.
      */