Merge "Add default calls/SMS subscription prefs to mobile details page"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b1edbb4..a4ecd3a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10373,6 +10373,17 @@
     <string name="mobile_data_settings_title">Mobile data</string>
     <!-- Mobile network settings screen, title of Mobile data switch preference [CHAR LIMIT=NONE] -->
     <string name="mobile_data_settings_summary">Access data using mobile network</string>
+    <!-- Mobile network settings screen, title of item showing the name of the default subscription
+     that will be used for calls. This only appears in multi-SIM mode. [CHAR LIMIT=NONE] -->
+    <string name="calls_preference">Calls preference</string>
+    <!-- Mobile network settings screen, title of item showing the name of the default subscription
+     that will be used for SMS messages. This only appears in multi-SIM mode. [CHAR LIMIT=NONE] -->
+    <string name="sms_preference">SMS preference</string>
+    <!-- Mobile network settings screen, a label in a chooser dialog that appears when choosing the
+    default subscription to use for either calls or SMS when in multi-SIM mode. This label means
+    that the user will be asked which mobile network subscription to use every time they place a
+    call or send an SMS, instead of defaulting to one particular subscription. [CHAR LIMIT=40]-->
+    <string name="calls_and_sms_ask_every_time">Ask every time</string>
 
     <!-- Summary of the 'Mobile network' item on the Network & internet page when there is no mobile
          service setup yet (eg no SIM card inserted and no eSIM configured). Tapping it leads to a
diff --git a/res/xml/mobile_network_settings_v2.xml b/res/xml/mobile_network_settings_v2.xml
index 7a19c32..6273ad9 100644
--- a/res/xml/mobile_network_settings_v2.xml
+++ b/res/xml/mobile_network_settings_v2.xml
@@ -17,24 +17,37 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="mobile_network_pref_screen"
-    settings:initialExpandedChildrenCount="5">
+    settings:initialExpandedChildrenCount="7">
 
     <com.android.settings.datausage.DataUsageSummaryPreference
         android:key="status_header"
         android:visibility="gone"
         android:selectable="false" />
 
+    <ListPreference
+        android:key="calls_preference"
+        android:title="@string/calls_preference"
+        settings:controller="com.android.settings.network.telephony.CallsDefaultSubscriptionController"
+        settings:allowDividerAbove="true" />
+
+    <ListPreference
+        android:key="sms_preference"
+        android:title="@string/sms_preference"
+        settings:controller="com.android.settings.network.telephony.SmsDefaultSubscriptionController" />
+
     <Preference
         android:key="cdma_lte_data_service_key"
         android:title="@string/cdma_lte_data_service"
-        settings:controller="com.android.settings.network.telephony.DataServiceSetupPreferenceController">
-    </Preference>
+        settings:controller="com.android.settings.network.telephony.DataServiceSetupPreferenceController"
+        settings:allowDividerAbove="true"
+        settings:allowDividerBelow="false" />
 
     <SwitchPreference
         android:key="mobile_data_enable"
         android:title="@string/mobile_data_settings_title"
         android:summary="@string/mobile_data_settings_summary"
-        settings:controller="com.android.settings.network.telephony.MobileDataPreferenceController"/>
+        settings:controller="com.android.settings.network.telephony.MobileDataPreferenceController"
+        settings:allowDividerAbove="true"/>
 
     <com.android.settingslib.RestrictedSwitchPreference
         android:key="button_roaming_key"
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index fbc6edd..237e08a 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -30,7 +30,7 @@
     private static List<SubscriptionInfo> sResultsForTesting;
 
     @VisibleForTesting
-    static void setAvailableSubscriptionsForTesting(List<SubscriptionInfo> results) {
+    public static void setAvailableSubscriptionsForTesting(List<SubscriptionInfo> results) {
         sResultsForTesting = results;
     }
 
diff --git a/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
new file mode 100644
index 0000000..008a3e4
--- /dev/null
+++ b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 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.settings.network.telephony;
+
+import android.content.Context;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+public class CallsDefaultSubscriptionController extends DefaultSubscriptionController {
+
+    public CallsDefaultSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    protected SubscriptionInfo getDefaultSubscriptionInfo() {
+        return mManager.getDefaultVoiceSubscriptionInfo();
+    }
+
+    @Override
+    protected int getDefaultSubscriptionId() {
+        return SubscriptionManager.getDefaultVoiceSubscriptionId();
+    }
+
+    @Override
+    protected void setDefaultSubscription(int subscriptionId) {
+        mManager.setDefaultVoiceSubId(subscriptionId);
+    }
+}
diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
new file mode 100644
index 0000000..bca6750
--- /dev/null
+++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2019 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.settings.network.telephony;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
+
+import android.content.Context;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.network.SubscriptionUtil;
+import com.android.settings.network.SubscriptionsChangeListener;
+
+import java.util.List;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+/**
+ * This implements common controller functionality for a Preference letting the user see/change
+ * what mobile network subscription is used by default for some service controlled by the
+ * SubscriptionManager. This can be used for services such as Calls or SMS.
+ */
+public abstract class DefaultSubscriptionController extends BasePreferenceController implements
+        LifecycleObserver, Preference.OnPreferenceChangeListener,
+        SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
+    private static final String TAG = "DefaultSubController";
+
+    protected SubscriptionsChangeListener mChangeListener;
+    protected ListPreference mPreference;
+    protected SubscriptionManager mManager;
+
+    public DefaultSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mManager = context.getSystemService(SubscriptionManager.class);
+        mChangeListener = new SubscriptionsChangeListener(context, this);
+    }
+
+    public void init(Lifecycle lifecycle) {
+        lifecycle.addObserver(this);
+    }
+
+    /** @return SubscriptionInfo for the default subscription for the service, or null if there
+     * isn't one. */
+    protected abstract SubscriptionInfo getDefaultSubscriptionInfo();
+
+    /** @return the id of the default subscription for the service, or
+     * SubscriptionManager.INVALID_SUBSCRIPTION_ID if there isn't one. */
+    protected abstract int getDefaultSubscriptionId();
+
+    /** Called to change the default subscription for the service. */
+    protected abstract void setDefaultSubscription(int subscriptionId);
+
+    @Override
+    public int getAvailabilityStatus() {
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+        if (subs.size() > 1) {
+            return AVAILABLE;
+        } else {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+    }
+
+    @OnLifecycleEvent(ON_RESUME)
+    public void onResume() {
+        mChangeListener.start();
+        updateEntries();
+    }
+
+    @OnLifecycleEvent(ON_PAUSE)
+    public void onPause() {
+        mChangeListener.stop();
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+        updateEntries();
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        final SubscriptionInfo info = getDefaultSubscriptionInfo();
+        if (info != null) {
+            return info.getDisplayName();
+        } else {
+            return mContext.getString(R.string.calls_and_sms_ask_every_time);
+        }
+    }
+
+    private void updateEntries() {
+        if (mPreference == null) {
+            return;
+        }
+        if (!isAvailable()) {
+            mPreference.setVisible(false);
+            return;
+        }
+        mPreference.setVisible(true);
+
+        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+
+        // We'll have one entry for each available subscription, plus one for a "ask me every
+        // time" entry at the end.
+        final CharSequence[] displayNames = new CharSequence[subs.size() + 1];
+        final CharSequence[] subscriptionIds = new CharSequence[subs.size() + 1];
+
+        final int serviceDefaultSubId = getDefaultSubscriptionId();
+        boolean subIsAvailable = false;
+
+        int i = 0;
+        for (; i < subs.size(); i++) {
+            displayNames[i] = subs.get(i).getDisplayName();
+            final int subId = subs.get(i).getSubscriptionId();
+            subscriptionIds[i] = Integer.toString(subId);
+            if (subId == serviceDefaultSubId) {
+                subIsAvailable = true;
+            }
+        }
+        // Add the extra "Ask every time" value at the end.
+        displayNames[i] = mContext.getString(R.string.calls_and_sms_ask_every_time);
+        subscriptionIds[i] = Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        mPreference.setEntries(displayNames);
+        mPreference.setEntryValues(subscriptionIds);
+
+        if (subIsAvailable) {
+            mPreference.setValue(Integer.toString(serviceDefaultSubId));
+        } else {
+            mPreference.setValue(Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        final int subscriptionId = Integer.parseInt((String) newValue);
+        setDefaultSubscription(subscriptionId);
+        refreshSummary(mPreference);
+        return true;
+    }
+
+    @Override
+    public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
+    }
+
+    @Override
+    public void onSubscriptionsChanged() {
+        if (mPreference != null) {
+            updateEntries();
+            refreshSummary(mPreference);
+        }
+    }
+}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 9665c09..5201586 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -126,6 +126,10 @@
     public void onAttach(Context context) {
         super.onAttach(context);
 
+        if (FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
+          use(CallsDefaultSubscriptionController.class).init(getLifecycle());
+          use(SmsDefaultSubscriptionController.class).init(getLifecycle());
+        }
         use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
         use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
         use(ApnPreferenceController.class).init(mSubId);
diff --git a/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
new file mode 100644
index 0000000..b999219
--- /dev/null
+++ b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 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.settings.network.telephony;
+
+import android.content.Context;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+public class SmsDefaultSubscriptionController extends DefaultSubscriptionController {
+
+    public SmsDefaultSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    protected SubscriptionInfo getDefaultSubscriptionInfo() {
+        return mManager.getDefaultSmsSubscriptionInfo();
+    }
+
+    @Override
+    protected int getDefaultSubscriptionId() {
+        return SubscriptionManager.getDefaultSmsSubscriptionId();
+    }
+
+    @Override
+    protected void setDefaultSubscription(int subscriptionId) {
+        mManager.setDefaultSmsSubId(subscriptionId);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
new file mode 100644
index 0000000..f7a2567
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2019 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.settings.network.telephony;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import com.android.settings.R;
+import com.android.settings.network.SubscriptionUtil;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.Arrays;
+
+import androidx.preference.ListPreference;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(RobolectricTestRunner.class)
+public class DefaultSubscriptionControllerTest {
+    @Mock
+    private SubscriptionManager mManager;
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private ListPreference mListPreference;
+    private Context mContext;
+    private DefaultSubscriptionController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mManager);
+        final String key = "prefkey";
+        mController = spy(new TestDefaultSubscriptionController(mContext, key));
+        mListPreference = spy(new ListPreference(mContext));
+        when(mScreen.findPreference(key)).thenReturn(mListPreference);
+    }
+
+    @After
+    public void tearDown() {
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
+    }
+
+    @Test
+    public void getAvailabilityStatus_onlyOneSubscription_notAvailable() {
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(
+                createMockSub(1, "sub1")));
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_twoSubscriptions_isAvailable() {
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(
+                createMockSub(1, "sub1"),
+                createMockSub(2, "sub2")));
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void displayPreference_twoSubscriptionsSub1Default_correctListPreferenceValues() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+
+        final CharSequence entry = mListPreference.getEntry();
+        final String value = mListPreference.getValue();
+        assertThat(entry).isEqualTo("sub1");
+        assertThat(value).isEqualTo("111");
+
+        final CharSequence[] entries = mListPreference.getEntries();
+        assertThat(entries.length).isEqualTo(3);
+        assertThat(entries[0]).isEqualTo("sub1");
+        assertThat(entries[1]).isEqualTo("sub2");
+        assertThat(entries[2]).isEqualTo(mContext.getString(R.string.calls_and_sms_ask_every_time));
+
+        final CharSequence[] entryValues = mListPreference.getEntryValues();
+        assertThat(entryValues.length).isEqualTo(3);
+        assertThat(entryValues[0]).isEqualTo("111");
+        assertThat(entryValues[1]).isEqualTo("222");
+        assertThat(entryValues[2]).isEqualTo(
+                Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+    }
+
+    @Test
+    public void displayPreference_twoSubscriptionsSub2Default_correctListPreferenceValues() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        doReturn(sub2.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+
+        final CharSequence entry = mListPreference.getEntry();
+        final String value = mListPreference.getValue();
+        assertThat(entry).isEqualTo("sub2");
+        assertThat(value).isEqualTo("222");
+
+        final CharSequence[] entries = mListPreference.getEntries();
+        assertThat(entries.length).isEqualTo(3);
+        assertThat(entries[0]).isEqualTo("sub1");
+        assertThat(entries[1]).isEqualTo("sub2");
+        assertThat(entries[2]).isEqualTo(mContext.getString(R.string.calls_and_sms_ask_every_time));
+
+        final CharSequence[] entryValues = mListPreference.getEntryValues();
+        assertThat(entryValues.length).isEqualTo(3);
+        assertThat(entryValues[0]).isEqualTo("111");
+        assertThat(entryValues[1]).isEqualTo("222");
+        assertThat(entryValues[2]).isEqualTo(
+                Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+    }
+
+    @Test
+    public void onPreferenceChange_prefChangedToSub2_callbackCalledCorrectly() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+        mListPreference.setValue("222");
+        mController.onPreferenceChange(mListPreference, "222");
+        verify(mController).setDefaultSubscription(eq(222));
+    }
+
+    @Test
+    public void onPreferenceChange_prefChangedToAlwaysAsk_callbackCalledCorrectly() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+        mListPreference.setValue(Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+        mController.onPreferenceChange(mListPreference,
+                Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+        verify(mController).setDefaultSubscription(
+                eq(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+    }
+
+    @Test
+    public void onSubscriptionsChanged_twoSubscriptionsDefaultChanges_selectedEntryGetsUpdated() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+        assertThat( mListPreference.getEntry()).isEqualTo("sub1");
+        assertThat(mListPreference.getValue()).isEqualTo("111");
+
+        doReturn(sub2.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.onSubscriptionsChanged();
+        assertThat( mListPreference.getEntry()).isEqualTo("sub2");
+        assertThat(mListPreference.getValue()).isEqualTo("222");
+    }
+
+    @Test
+    public void onSubscriptionsChanged_goFromTwoSubscriptionsToOne_prefDisappears() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+        assertThat(mController.isAvailable()).isTrue();
+        assertThat(mListPreference.isVisible()).isTrue();
+
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
+        mController.onSubscriptionsChanged();
+
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mListPreference.isVisible()).isFalse();
+    }
+
+    @Test
+    public void onSubscriptionsChanged_goFromOneSubscriptionToTwo_prefAppears() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
+        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mListPreference.isVisible()).isFalse();
+
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        mController.onSubscriptionsChanged();
+
+        assertThat(mController.isAvailable()).isTrue();
+        assertThat(mListPreference.isVisible()).isTrue();
+    }
+
+    @Test
+    public void onSubscriptionsChanged_goFromTwoToThreeSubscriptions_listGetsUpdated() {
+        final SubscriptionInfo sub1 = createMockSub(111, "sub1");
+        final SubscriptionInfo sub2 = createMockSub(222, "sub2");
+        final SubscriptionInfo sub3 = createMockSub(333, "sub3");
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+
+        mController.displayPreference(mScreen);
+        assertThat(mListPreference.getEntries().length).isEqualTo(3);
+
+        SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3));
+        mController.onSubscriptionsChanged();
+
+        assertThat(mController.isAvailable()).isTrue();
+        assertThat(mListPreference.isVisible()).isTrue();
+        final CharSequence[] entries = mListPreference.getEntries();
+        final CharSequence[] entryValues = mListPreference.getEntryValues();
+        assertThat(entries.length).isEqualTo(4);
+        assertThat(entries[0].toString()).isEqualTo("sub1");
+        assertThat(entries[1].toString()).isEqualTo("sub2");
+        assertThat(entries[2].toString()).isEqualTo("sub3");
+        assertThat(entries[3].toString()).isEqualTo(
+                mContext.getString(R.string.calls_and_sms_ask_every_time));
+        assertThat(entryValues[0].toString()).isEqualTo("111");
+        assertThat(entryValues[1].toString()).isEqualTo("222");
+        assertThat(entryValues[2].toString()).isEqualTo("333");
+        assertThat(entryValues[3].toString()).isEqualTo(
+                Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+    }
+
+    private SubscriptionInfo createMockSub(int id, String displayName) {
+        final SubscriptionInfo sub = mock(SubscriptionInfo.class);
+        when(sub.getSubscriptionId()).thenReturn(id);
+        when(sub.getDisplayName()).thenReturn(displayName);
+        return sub;
+    }
+
+    private class TestDefaultSubscriptionController extends DefaultSubscriptionController {
+
+        public TestDefaultSubscriptionController(Context context, String preferenceKey) {
+            super(context, preferenceKey);
+        }
+
+        @Override
+        protected SubscriptionInfo getDefaultSubscriptionInfo() {
+            return null;
+        }
+
+        @Override
+        protected int getDefaultSubscriptionId() {
+            return 0;
+        }
+
+        @Override
+        protected void setDefaultSubscription(int subscriptionId) {
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
index 0240bd8..55a4224 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSettingsTest.java
@@ -85,7 +85,13 @@
     }
 
     @Test
-    public void onAttach_noCrash() {
+    public void onAttach_noV2Flag_noCrash() {
+        mFragment.onAttach(mContext);
+    }
+
+    @Test
+    public void onAttach_v2Flag_noCrash() {
+        FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, true);
         mFragment.onAttach(mContext);
     }