From f4ee4ef3bf249a34740c6e6bf1e3a5bf303f0d99 Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Fri, 11 Jan 2019 13:11:57 -0800 Subject: [PATCH] Add page listing multiple mobile networks When a device supports simultaneous connection to multiple mobile networks, we want the "Mobile network" entry on the Network & internet page to list the number of active SIMs and when clicked, go to a page that lists them all. Bug: 116349402 Test: make RunSettingsRoboTests Change-Id: Ie642d7801cda07dcbbe74d42c234db6605566be4 --- res/values/strings.xml | 28 ++++ res/xml/mobile_network_list.xml | 28 ++++ res/xml/network_and_internet_v2.xml | 5 +- .../network/MobileNetworkListController.java | 149 ++++++++++++++++++ .../network/MobileNetworkListFragment.java | 71 +++++++++ .../network/MobileNetworkSummaryController.java | 147 ++++++++++++++++++ .../settings/network/NetworkDashboardFragment.java | 19 ++- .../network/MobileNetworkListControllerTest.java | 152 ++++++++++++++++++ .../MobileNetworkSummaryControllerTest.java | 171 +++++++++++++++++++++ 9 files changed, 763 insertions(+), 7 deletions(-) create mode 100644 res/xml/mobile_network_list.xml create mode 100644 src/com/android/settings/network/MobileNetworkListController.java create mode 100644 src/com/android/settings/network/MobileNetworkListFragment.java create mode 100644 src/com/android/settings/network/MobileNetworkSummaryController.java create mode 100644 tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 9f5b562c2b..a07592d454 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10320,6 +10320,34 @@ Access data using mobile network + + Add a network + + + %1$d SIM + %1$d SIMs + + + + Add more + + Active SIM + + Inactive SIM + + Active eSIM + + Inactive eSIM + Preferred network type diff --git a/res/xml/mobile_network_list.xml b/res/xml/mobile_network_list.xml new file mode 100644 index 0000000000..81704e5592 --- /dev/null +++ b/res/xml/mobile_network_list.xml @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/res/xml/network_and_internet_v2.xml b/res/xml/network_and_internet_v2.xml index 8e0b4263ed..bde7889ce3 100644 --- a/res/xml/network_and_internet_v2.xml +++ b/res/xml/network_and_internet_v2.xml @@ -40,15 +40,14 @@ - + settings:useAdminDisabledSummary="true" /> mPreferences; + + public MobileNetworkListController(Context context, Lifecycle lifecycle) { + super(context); + mSubscriptionManager = context.getSystemService(SubscriptionManager.class); + mChangeListener = new SubscriptionsChangeListener(context, this); + mPreferences = new ArrayMap<>(); + lifecycle.addObserver(this); + } + + @OnLifecycleEvent(ON_RESUME) + public void onResume() { + mChangeListener.start(); + update(); + } + + @OnLifecycleEvent(ON_PAUSE) + public void onPause() { + mChangeListener.stop(); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreferenceScreen = screen; + update(); + } + + private void update() { + if (mPreferenceScreen == null) { + return; + } + + // Since we may already have created some preferences previously, we first grab the list of + // those, then go through the current available subscriptions making sure they are all + // present in the screen, and finally remove any now-outdated ones. + final Map existingPreferences = mPreferences; + mPreferences = new ArrayMap<>(); + + final List subscriptions = SubscriptionUtil.getAvailableSubscriptions( + mSubscriptionManager); + for (SubscriptionInfo info : subscriptions) { + int subId = info.getSubscriptionId(); + Preference pref = existingPreferences.remove(subId); + if (pref == null) { + pref = new Preference(mPreferenceScreen.getContext()); + mPreferenceScreen.addPreference(pref); + } + pref.setTitle(info.getDisplayName()); + + if (info.isEmbedded()) { + if (mSubscriptionManager.isActiveSubscriptionId(subId)) { + pref.setSummary(R.string.mobile_network_active_esim); + } else { + pref.setSummary(R.string.mobile_network_inactive_esim); + } + } else { + if (mSubscriptionManager.isActiveSubscriptionId(subId)) { + pref.setSummary(R.string.mobile_network_active_sim); + } else { + pref.setSummary(R.string.mobile_network_inactive_sim); + } + } + + pref.setOnPreferenceClickListener(clickedPref -> { + final Intent intent = new Intent(mContext, MobileNetworkActivity.class); + intent.putExtra(Settings.EXTRA_SUB_ID, info.getSubscriptionId()); + mContext.startActivity(intent); + return true; + }); + mPreferences.put(subId, pref); + } + for (Preference pref : existingPreferences.values()) { + mPreferenceScreen.removePreference(pref); + } + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return null; + } + + @Override + public void onAirplaneModeChanged(boolean airplaneModeEnabled) { + } + + @Override + public void onSubscriptionsChanged() { + update(); + } +} diff --git a/src/com/android/settings/network/MobileNetworkListFragment.java b/src/com/android/settings/network/MobileNetworkListFragment.java new file mode 100644 index 0000000000..8787378349 --- /dev/null +++ b/src/com/android/settings/network/MobileNetworkListFragment.java @@ -0,0 +1,71 @@ +/* + * 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; + +import android.content.Context; +import android.provider.SearchIndexableResource; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.search.SearchIndexable; + +import java.util.ArrayList; +import java.util.List; + +@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) +public class MobileNetworkListFragment extends DashboardFragment { + private static final String LOG_TAG = "NetworkListFragment"; + + @Override + protected int getPreferenceScreenResId() { + return R.xml.mobile_network_list; + } + + @Override + protected String getLogTag() { + return LOG_TAG; + } + + @Override + public int getMetricsCategory() { + // TODO(asargent) - return SettingsEnums.MOBILE_NETWORK_LIST once the CL defining it has + // landed. + return 0; + } + + @Override + protected List createPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new MobileNetworkListController(getContext(), getLifecycle())); + return controllers; + } + + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final ArrayList result = new ArrayList<>(); + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.mobile_network_list; + result.add(sir); + return result; + } + }; +} diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java new file mode 100644 index 0000000000..bbc4ea4b21 --- /dev/null +++ b/src/com/android/settings/network/MobileNetworkSummaryController.java @@ -0,0 +1,147 @@ +/* + * 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; + +import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE; +import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; + +import android.content.Context; +import android.content.Intent; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; + +import com.android.settings.R; +import com.android.settings.network.telephony.MobileNetworkActivity; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.util.List; + +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.OnLifecycleEvent; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +public class MobileNetworkSummaryController extends AbstractPreferenceController implements + SubscriptionsChangeListener.SubscriptionsChangeListenerClient, LifecycleObserver { + private static final String TAG = "MobileNetSummaryCtlr"; + + private static final String KEY = "mobile_network_list"; + + private SubscriptionManager mSubscriptionManager; + private SubscriptionsChangeListener mChangeListener; + private PreferenceScreen mScreen; + + /** + * This controls the summary text and click behavior of the "Mobile network" item on the + * Network & internet page. There are 3 separate cases depending on the number of mobile network + * subscriptions: + *
    + *
  • No subscription: click action begins a UI flow to add a network subscription, and + * the summary text indicates this
  • + * + *
  • One subscription: click action takes you to details for that one network, and + * the summary text is the network name
  • + * + *
  • More than one subscription: click action takes you to a page listing the subscriptions, + * and the summary text gives the count of SIMs
  • + *
+ */ + public MobileNetworkSummaryController(Context context, Lifecycle lifecycle) { + super(context); + mSubscriptionManager = context.getSystemService(SubscriptionManager.class); + mChangeListener = new SubscriptionsChangeListener(context, this); + lifecycle.addObserver(this); + } + + @OnLifecycleEvent(ON_RESUME) + public void onResume() { + mChangeListener.start(); + update(); + } + + @OnLifecycleEvent(ON_PAUSE) + public void onPause() { + mChangeListener.stop(); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mScreen = screen; + } + + @Override + public CharSequence getSummary() { + final List subs = SubscriptionUtil.getAvailableSubscriptions( + mSubscriptionManager); + if (subs.isEmpty()) { + return mContext.getResources().getString(R.string.mobile_network_summary_add_a_network); + } else if (subs.size() == 1) { + return subs.get(0).getDisplayName(); + } else { + final int count = subs.size(); + return mContext.getResources().getQuantityString(R.plurals.mobile_network_summary_count, + count, count); + } + } + + private void update() { + if (mScreen != null) { + final Preference preference = mScreen.findPreference(getPreferenceKey()); + refreshSummary(preference); + final List subs = SubscriptionUtil.getAvailableSubscriptions( + mSubscriptionManager); + + preference.setOnPreferenceClickListener(null); + preference.setFragment(null); + if (subs.size() == 0) { + preference.setOnPreferenceClickListener((Preference pref) -> { + // TODO(asargent) - need to get correct intent to fire here + return true; + }); + } else if (subs.size() == 1) { + preference.setOnPreferenceClickListener((Preference pref) -> { + final Intent intent = new Intent(mContext, MobileNetworkActivity.class); + mContext.startActivity(intent); + return true; + }); + } else { + preference.setFragment(MobileNetworkListFragment.class.getCanonicalName()); + } + } + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return KEY; + } + + @Override + public void onAirplaneModeChanged(boolean airplaneModeEnabled) { + } + + @Override + public void onSubscriptionsChanged() { + update(); + } +} diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java index c2b4a2b1c0..efdb5561e9 100644 --- a/src/com/android/settings/network/NetworkDashboardFragment.java +++ b/src/com/android/settings/network/NetworkDashboardFragment.java @@ -96,8 +96,11 @@ public class NetworkDashboardFragment extends DashboardFragment implements new MobilePlanPreferenceController(context, mobilePlanHost); final WifiMasterSwitchPreferenceController wifiPreferenceController = new WifiMasterSwitchPreferenceController(context, metricsFeatureProvider); - final MobileNetworkPreferenceController mobileNetworkPreferenceController = - new MobileNetworkPreferenceController(context); + MobileNetworkPreferenceController mobileNetworkPreferenceController = null; + if (!FeatureFlagPersistent.isEnabled(context, FeatureFlags.NETWORK_INTERNET_V2)) { + mobileNetworkPreferenceController = new MobileNetworkPreferenceController(context); + } + final VpnPreferenceController vpnPreferenceController = new VpnPreferenceController(context); final PrivateDnsPreferenceController privateDnsPreferenceController = @@ -106,13 +109,21 @@ public class NetworkDashboardFragment extends DashboardFragment implements if (lifecycle != null) { lifecycle.addObserver(mobilePlanPreferenceController); lifecycle.addObserver(wifiPreferenceController); - lifecycle.addObserver(mobileNetworkPreferenceController); + if (mobileNetworkPreferenceController != null) { + lifecycle.addObserver(mobileNetworkPreferenceController); + } lifecycle.addObserver(vpnPreferenceController); lifecycle.addObserver(privateDnsPreferenceController); } final List controllers = new ArrayList<>(); - controllers.add(mobileNetworkPreferenceController); + + if (FeatureFlagPersistent.isEnabled(context, FeatureFlags.NETWORK_INTERNET_V2)) { + controllers.add(new MobileNetworkSummaryController(context, lifecycle)); + } + if (mobileNetworkPreferenceController != null) { + controllers.add(mobileNetworkPreferenceController); + } controllers.add(new TetherPreferenceController(context, lifecycle)); controllers.add(vpnPreferenceController); controllers.add(new ProxyPreferenceController(context)); diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java new file mode 100644 index 0000000000..1325650b46 --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/MobileNetworkListControllerTest.java @@ -0,0 +1,152 @@ +/* + * 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; + +import static android.provider.Settings.EXTRA_SUB_ID; +import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.telephony.SubscriptionInfo; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; + +import java.util.Arrays; + +import androidx.lifecycle.Lifecycle; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +@RunWith(RobolectricTestRunner.class) +public class MobileNetworkListControllerTest { + @Mock + private Lifecycle mLifecycle; + + @Mock + private PreferenceScreen mPreferenceScreen; + + private Context mContext; + private MobileNetworkListController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(Robolectric.setupActivity(Activity.class)); + when(mPreferenceScreen.getContext()).thenReturn(mContext); + mController = new MobileNetworkListController(mContext, mLifecycle); + } + + @After + public void tearDown() { + SubscriptionUtil.setAvailableSubscriptionsForTesting(null); + } + + @Test + public void displayPreference_noSubscriptions_noCrash() { + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + } + + @Test + public void displayPreference_twoSubscriptions_correctlySetup() { + final SubscriptionInfo sub1 = createMockSubscription(1, "sub1"); + final SubscriptionInfo sub2 = createMockSubscription(2, "sub2"); + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + + // Check that the preferences get created with the correct titles. + final ArgumentCaptor preferenceCaptor = ArgumentCaptor.forClass( + Preference.class); + verify(mPreferenceScreen, times(2)).addPreference(preferenceCaptor.capture()); + final Preference pref1 = preferenceCaptor.getAllValues().get(0); + final Preference pref2 = preferenceCaptor.getAllValues().get(1); + assertThat(pref1.getTitle()).isEqualTo("sub1"); + assertThat(pref2.getTitle()).isEqualTo("sub2"); + + // Check that the onclick listeners are setup to fire with the right subscription id. + final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + pref1.getOnPreferenceClickListener().onPreferenceClick(pref1); + pref2.getOnPreferenceClickListener().onPreferenceClick(pref2); + verify(mContext, times(2)).startActivity(intentCaptor.capture()); + final Intent intent1 = intentCaptor.getAllValues().get(0); + final Intent intent2 = intentCaptor.getAllValues().get(1); + assertThat(intent1.getIntExtra(EXTRA_SUB_ID, INVALID_SUBSCRIPTION_ID)).isEqualTo(1); + assertThat(intent2.getIntExtra(EXTRA_SUB_ID, INVALID_SUBSCRIPTION_ID)).isEqualTo(2); + } + + @Test + public void onSubscriptionsChanged_twoSubscriptionsOneChangesName_preferenceUpdated() { + final SubscriptionInfo sub1 = createMockSubscription(1, "sub1"); + final SubscriptionInfo sub2 = createMockSubscription(2, "sub2"); + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + final ArgumentCaptor preferenceCaptor = ArgumentCaptor.forClass( + Preference.class); + verify(mPreferenceScreen, times(2)).addPreference(preferenceCaptor.capture()); + + when(sub2.getDisplayName()).thenReturn("new name"); + mController.onSubscriptionsChanged(); + assertThat(preferenceCaptor.getAllValues().get(1).getTitle()).isEqualTo("new name"); + } + + @Test + public void onSubscriptionsChanged_startWithThreeSubsAndRemoveOne_correctPreferenceRemoved() { + final SubscriptionInfo sub1 = createMockSubscription(1, "sub1"); + final SubscriptionInfo sub2 = createMockSubscription(2, "sub2"); + final SubscriptionInfo sub3 = createMockSubscription(3, "sub3"); + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + final ArgumentCaptor preferenceCaptor = ArgumentCaptor.forClass( + Preference.class); + verify(mPreferenceScreen, times(3)).addPreference(preferenceCaptor.capture()); + + // remove sub2, and check that the second pref was removed from the screen + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub3)); + mController.onSubscriptionsChanged(); + final ArgumentCaptor removedPrefCaptor = ArgumentCaptor.forClass( + Preference.class); + verify(mPreferenceScreen).removePreference(removedPrefCaptor.capture()); + assertThat(removedPrefCaptor.getValue().getTitle()).isEqualTo("sub2"); + } + + private SubscriptionInfo createMockSubscription(int id, String displayName) { + final SubscriptionInfo sub = mock(SubscriptionInfo.class); + when(sub.getSubscriptionId()).thenReturn(id); + when(sub.getDisplayName()).thenReturn(displayName); + return sub; + } +} diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java new file mode 100644 index 0000000000..f0c012de52 --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java @@ -0,0 +1,171 @@ +/* + * 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; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.eq; +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.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.telephony.SubscriptionInfo; + +import com.android.settings.network.telephony.MobileNetworkActivity; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; + +import java.util.Arrays; + +import androidx.lifecycle.Lifecycle; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +@RunWith(RobolectricTestRunner.class) +public class MobileNetworkSummaryControllerTest { + @Mock + private Lifecycle mLifecycle; + @Mock + PreferenceScreen mPreferenceScreen; + + Preference mPreference; + + private Context mContext; + private MobileNetworkSummaryController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(Robolectric.setupActivity(Activity.class)); + mController = new MobileNetworkSummaryController(mContext, mLifecycle); + mPreference = new Preference(mContext); + mPreference.setKey(mController.getPreferenceKey()); + when(mPreferenceScreen.findPreference(eq(mController.getPreferenceKey()))).thenReturn( + mPreference); + } + + @After + public void tearDown() { + SubscriptionUtil.setAvailableSubscriptionsForTesting(null); + } + + @Test + public void getSummary_noSubscriptions_correctSummary() { + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + assertThat(mController.getSummary()).isEqualTo("Add a network"); + } + + @Test + public void getSummary_oneSubscription_correctSummaryAndClickHandler() { + SubscriptionInfo sub1 = mock(SubscriptionInfo.class); + when(sub1.getSubscriptionId()).thenReturn(1); + when(sub1.getDisplayName()).thenReturn("sub1"); + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + assertThat(mController.getSummary()).isEqualTo("sub1"); + assertThat(mPreference.getFragment()).isNull(); + mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference); + ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext).startActivity(intentCaptor.capture()); + assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo( + MobileNetworkActivity.class.getName()); + } + + @Test + public void getSummary_twoSubscriptions_correctSummaryAndFragment() { + SubscriptionInfo sub1 = mock(SubscriptionInfo.class); + SubscriptionInfo sub2 = mock(SubscriptionInfo.class); + when(sub1.getSubscriptionId()).thenReturn(1); + when(sub2.getSubscriptionId()).thenReturn(2); + + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + assertThat(mController.getSummary()).isEqualTo("2 SIMs"); + assertThat(mPreference.getFragment()).isEqualTo(MobileNetworkListFragment.class.getName()); + } + + @Test + public void getSummaryAfterUpdate_twoSubscriptionsBecomesOne_correctSummaryAndFragment() { + SubscriptionInfo sub1 = mock(SubscriptionInfo.class); + SubscriptionInfo sub2 = mock(SubscriptionInfo.class); + when(sub1.getSubscriptionId()).thenReturn(1); + when(sub2.getSubscriptionId()).thenReturn(2); + when(sub1.getDisplayName()).thenReturn("sub1"); + when(sub2.getDisplayName()).thenReturn("sub2"); + + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + assertThat(mController.getSummary()).isEqualTo("2 SIMs"); + assertThat(mPreference.getFragment()).isEqualTo(MobileNetworkListFragment.class.getName()); + + // Simulate sub2 having disappeared - the end result should change to be the same as + // if there were just one subscription. + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); + mController.onSubscriptionsChanged(); + assertThat(mController.getSummary()).isEqualTo("sub1"); + assertThat(mPreference.getFragment()).isNull(); + mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference); + ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext).startActivity(intentCaptor.capture()); + assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo( + MobileNetworkActivity.class.getName()); + } + + @Test + public void getSummaryAfterUpdate_oneSubscriptionBecomesTwo_correctSummaryAndFragment() { + SubscriptionInfo sub1 = mock(SubscriptionInfo.class); + SubscriptionInfo sub2 = mock(SubscriptionInfo.class); + when(sub1.getSubscriptionId()).thenReturn(1); + when(sub2.getSubscriptionId()).thenReturn(2); + when(sub1.getDisplayName()).thenReturn("sub1"); + when(sub2.getDisplayName()).thenReturn("sub2"); + + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + assertThat(mController.getSummary()).isEqualTo("sub1"); + assertThat(mPreference.getFragment()).isNull(); + mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference); + ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext).startActivity(intentCaptor.capture()); + assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo( + MobileNetworkActivity.class.getName()); + + // Simulate sub2 appearing in the list of subscriptions and check the results. + SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2)); + mController.displayPreference(mPreferenceScreen); + mController.onResume(); + assertThat(mController.getSummary()).isEqualTo("2 SIMs"); + assertThat(mPreference.getFragment()).isEqualTo(MobileNetworkListFragment.class.getName()); + } +} -- 2.11.0