Make taps on subscriptions in multi-network header go to mobile page
This CL does 2 things: -Makes the MobileNetworkActivity class capable of showing details for "available" in addition to just "active" networks. This is useful for dual-standby devices where one subscription is active and another is registered but not currently active. It also changes the title of this screen to be the network display name (defaults to the carrier name but can be customized by the user) instead of the generic "Mobile network". -Wires up the subscription entries in the multi-network header (which only appears when a device has multiple subscriptions) so that taps on a subscription preference bring you to the MobileNetworkActivity screen to show details for that network. Bug: 116349402 Test: make RunSettingsRoboTests Change-Id: I0e985652c1d8ec3c597b6b6e4426d222e2ad5352
This commit is contained in:
@@ -17,7 +17,6 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
android:key="mobile_network_pref_screen"
|
android:key="mobile_network_pref_screen"
|
||||||
android:title="@string/network_settings_title"
|
|
||||||
settings:initialExpandedChildrenCount="4">
|
settings:initialExpandedChildrenCount="4">
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
|
@@ -20,10 +20,13 @@ import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
|
|||||||
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
|
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.network.telephony.MobileNetworkActivity;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -125,7 +128,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
mSubscriptionPreferences = new ArrayMap<>();
|
mSubscriptionPreferences = new ArrayMap<>();
|
||||||
|
|
||||||
int order = mStartOrder;
|
int order = mStartOrder;
|
||||||
for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mManager) ) {
|
for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mManager)) {
|
||||||
final int subId = info.getSubscriptionId();
|
final int subId = info.getSubscriptionId();
|
||||||
Preference pref = existingPrefs.remove(subId);
|
Preference pref = existingPrefs.remove(subId);
|
||||||
if (pref == null) {
|
if (pref == null) {
|
||||||
@@ -139,8 +142,9 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
|||||||
// TODO(asargent) - set summary here to indicate default for calls/sms and data
|
// TODO(asargent) - set summary here to indicate default for calls/sms and data
|
||||||
|
|
||||||
pref.setOnPreferenceClickListener(clickedPref -> {
|
pref.setOnPreferenceClickListener(clickedPref -> {
|
||||||
// TODO(asargent) - make this start MobileNetworkActivity once we've
|
final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
|
||||||
// added support for it to take a subscription id
|
intent.putExtra(Settings.EXTRA_SUB_ID, subId);
|
||||||
|
mContext.startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -25,7 +25,6 @@ import android.os.Bundle;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
@@ -43,14 +42,12 @@ import com.android.settings.core.SettingsBaseActivity;
|
|||||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MobileNetworkActivity extends SettingsBaseActivity {
|
public class MobileNetworkActivity extends SettingsBaseActivity {
|
||||||
|
|
||||||
private static final String TAG = "MobileSettingsActivity";
|
private static final String TAG = "MobileNetworkActivity";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String MOBILE_SETTINGS_TAG = "mobile_settings:";
|
static final String MOBILE_SETTINGS_TAG = "mobile_settings:";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -94,6 +91,13 @@ public class MobileNetworkActivity extends SettingsBaseActivity {
|
|||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the title to the name of the subscription. If we don't have subscription info, the
|
||||||
|
// title will just default to the label for this activity that's already specified in
|
||||||
|
// AndroidManifest.xml.
|
||||||
|
final SubscriptionInfo subscription = getSubscription();
|
||||||
|
if (subscription != null) {
|
||||||
|
setTitle(subscription.getDisplayName());
|
||||||
|
}
|
||||||
updateSubscriptions(savedInstanceState);
|
updateSubscriptions(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,25 +140,41 @@ public class MobileNetworkActivity extends SettingsBaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current subId to display. First check whether intent has {@link
|
* Get the current subscription to display. First check whether intent has {@link
|
||||||
* Settings#EXTRA_SUB_ID}. If not, just display first one in list
|
* Settings#EXTRA_SUB_ID} and if so find the subscription with that id. If not, just return the
|
||||||
* since it is already sorted by sim slot.
|
* first one in the mSubscriptionInfos list since it is already sorted by sim slot.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
int getSubscriptionId() {
|
SubscriptionInfo getSubscription() {
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
final int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
|
final int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
|
||||||
if (subId != SUB_ID_NULL && mSubscriptionManager.isActiveSubscriptionId(subId)) {
|
if (subId != SUB_ID_NULL) {
|
||||||
return subId;
|
for (SubscriptionInfo subscription :
|
||||||
|
mSubscriptionManager.getAvailableSubscriptionInfoList()) {
|
||||||
|
if (subscription.getSubscriptionId() == subId) {
|
||||||
|
return subscription;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(mSubscriptionInfos)) {
|
if (CollectionUtils.isEmpty(mSubscriptionInfos)) {
|
||||||
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
return null;
|
||||||
}
|
}
|
||||||
|
return mSubscriptionInfos.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
return mSubscriptionInfos.get(0).getSubscriptionId();
|
/**
|
||||||
|
* Get the current subId to display.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
int getSubscriptionId() {
|
||||||
|
final SubscriptionInfo subscription = getSubscription();
|
||||||
|
if (subscription != null) {
|
||||||
|
return subscription.getSubscriptionId();
|
||||||
|
}
|
||||||
|
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@@ -16,33 +16,40 @@
|
|||||||
|
|
||||||
package com.android.settings.network;
|
package com.android.settings.network;
|
||||||
|
|
||||||
|
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -70,7 +77,7 @@ public class SubscriptionsPreferenceControllerTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(Robolectric.setupActivity(Activity.class));
|
||||||
mLifecycleOwner = () -> mLifecycle;
|
mLifecycleOwner = () -> mLifecycle;
|
||||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||||
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
|
||||||
@@ -83,6 +90,11 @@ public class SubscriptionsPreferenceControllerTest {
|
|||||||
KEY, 5);
|
KEY, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isAvailable_oneSubscription_availableFalse() {
|
public void isAvailable_oneSubscription_availableFalse() {
|
||||||
SubscriptionUtil.setAvailableSubscriptionsForTesting(
|
SubscriptionUtil.setAvailableSubscriptionsForTesting(
|
||||||
@@ -215,4 +227,57 @@ public class SubscriptionsPreferenceControllerTest {
|
|||||||
verify(mPreferenceCategory, times(3)).addPreference(captor.capture());
|
verify(mPreferenceCategory, times(3)).addPreference(captor.capture());
|
||||||
assertThat(captor.getValue().getTitle()).isEqualTo("sub3");
|
assertThat(captor.getValue().getTitle()).isEqualTo("sub3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to create a specified number of subscriptions, display them, and then click on one and
|
||||||
|
* verify that the intent fires and has the right subscription id extra.
|
||||||
|
*
|
||||||
|
* @param subscriptionCount the number of subscriptions
|
||||||
|
* @param selectedPrefIndex index of the subscription to click on
|
||||||
|
*/
|
||||||
|
private void runPreferenceClickTest(int subscriptionCount, int selectedPrefIndex) {
|
||||||
|
final ArrayList<SubscriptionInfo> subscriptions = new ArrayList<>();
|
||||||
|
for (int i = 0; i < subscriptionCount; i++) {
|
||||||
|
final SubscriptionInfo sub = mock(SubscriptionInfo.class);
|
||||||
|
doReturn(i + 1).when(sub).getSubscriptionId();
|
||||||
|
subscriptions.add(sub);
|
||||||
|
}
|
||||||
|
SubscriptionUtil.setAvailableSubscriptionsForTesting(subscriptions);
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
final ArgumentCaptor<Preference> prefCaptor = ArgumentCaptor.forClass(Preference.class);
|
||||||
|
verify(mPreferenceCategory, times(subscriptionCount)).addPreference(prefCaptor.capture());
|
||||||
|
final List<Preference> prefs = prefCaptor.getAllValues();
|
||||||
|
final Preference pref = prefs.get(selectedPrefIndex);
|
||||||
|
pref.getOnPreferenceClickListener().onPreferenceClick(pref);
|
||||||
|
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||||
|
verify(mContext).startActivity(intentCaptor.capture());
|
||||||
|
final Intent intent = intentCaptor.getValue();
|
||||||
|
assertThat(intent).isNotNull();
|
||||||
|
assertThat(intent.hasExtra(Settings.EXTRA_SUB_ID)).isTrue();
|
||||||
|
final int subIdFromIntent = intent.getIntExtra(Settings.EXTRA_SUB_ID,
|
||||||
|
INVALID_SUBSCRIPTION_ID);
|
||||||
|
assertThat(subIdFromIntent).isEqualTo(
|
||||||
|
subscriptions.get(selectedPrefIndex).getSubscriptionId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void twoPreferences_firstPreferenceClicked_correctIntentFires() {
|
||||||
|
runPreferenceClickTest(2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void twoPreferences_secondPreferenceClicked_correctIntentFires() {
|
||||||
|
runPreferenceClickTest(2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void threePreferences_secondPreferenceClicked_correctIntentFires() {
|
||||||
|
runPreferenceClickTest(3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void threePreferences_thirdPreferenceClicked_correctIntentFires() {
|
||||||
|
runPreferenceClickTest(3, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -143,6 +143,9 @@ public class MobileNetworkActivityTest {
|
|||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
intent.putExtra(Settings.EXTRA_SUB_ID, CURRENT_SUB_ID);
|
intent.putExtra(Settings.EXTRA_SUB_ID, CURRENT_SUB_ID);
|
||||||
doReturn(intent).when(mMobileNetworkActivity).getIntent();
|
doReturn(intent).when(mMobileNetworkActivity).getIntent();
|
||||||
|
mSubscriptionInfos.add(mSubscriptionInfo);
|
||||||
|
mSubscriptionInfos.add(mSubscriptionInfo2);
|
||||||
|
doReturn(mSubscriptionInfos).when(mSubscriptionManager).getAvailableSubscriptionInfoList();
|
||||||
doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(CURRENT_SUB_ID);
|
doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(CURRENT_SUB_ID);
|
||||||
|
|
||||||
assertThat(mMobileNetworkActivity.getSubscriptionId()).isEqualTo(CURRENT_SUB_ID);
|
assertThat(mMobileNetworkActivity.getSubscriptionId()).isEqualTo(CURRENT_SUB_ID);
|
||||||
|
Reference in New Issue
Block a user