Fix some problems with the "Mobile network" preference

This fixes a few issues with the "Mobile network" preference that shows
on the Network & internet page:

-The pref should not be available at all if the device is wifi-only.

-The pref should be disabled in airplane mode.

-If eSIM support is disabled, we need to disable entry points for adding
 a new eSIM subscription (the summary and click handler in single-SIM
 mode with no physical SIM, and the 'add' button in dual-SIM mode).

Bug: 116349402
Test: make RunSettingsRoboTests
Change-Id: Ic6fe426e9f890d80b399d48a2c9984d4d8b02a10
This commit is contained in:
Antony Sargent
2019-02-08 16:41:30 -08:00
parent 12cec79889
commit 475dde51b6
3 changed files with 132 additions and 14 deletions

View File

@@ -31,6 +31,7 @@ import android.telephony.euicc.EuiccManager;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.network.telephony.MobileNetworkActivity; import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settings.widget.AddPreference; import com.android.settings.widget.AddPreference;
import com.android.settingslib.Utils;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import java.util.List; import java.util.List;
@@ -50,6 +51,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
private SubscriptionManager mSubscriptionManager; private SubscriptionManager mSubscriptionManager;
private SubscriptionsChangeListener mChangeListener; private SubscriptionsChangeListener mChangeListener;
private TelephonyManager mTelephonyMgr; private TelephonyManager mTelephonyMgr;
private EuiccManager mEuiccManager;
private AddPreference mPreference; private AddPreference mPreference;
/** /**
@@ -71,6 +73,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
super(context); super(context);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class); mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
mTelephonyMgr = mContext.getSystemService(TelephonyManager.class); mTelephonyMgr = mContext.getSystemService(TelephonyManager.class);
mEuiccManager = mContext.getSystemService(EuiccManager.class);
mChangeListener = new SubscriptionsChangeListener(context, this); mChangeListener = new SubscriptionsChangeListener(context, this);
lifecycle.addObserver(this); lifecycle.addObserver(this);
} }
@@ -97,7 +100,11 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions( final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
mSubscriptionManager); mSubscriptionManager);
if (subs.isEmpty()) { if (subs.isEmpty()) {
return mContext.getResources().getString(R.string.mobile_network_summary_add_a_network); if (mEuiccManager.isEnabled()) {
return mContext.getResources().getString(
R.string.mobile_network_summary_add_a_network);
}
return null;
} else if (subs.size() == 1) { } else if (subs.size() == 1) {
return subs.get(0).getDisplayName(); return subs.get(0).getDisplayName();
} else { } else {
@@ -112,20 +119,22 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
mContext.startActivity(intent); mContext.startActivity(intent);
} }
private boolean shouldEnableAddButton() { private boolean shouldShowAddButton() {
// The add button should only show up if the device is in multi-sim mode. // The add button should only show up if the device is in multi-sim mode and the eSIM
return mTelephonyMgr.getMultiSimConfiguration() != UNKNOWN; // manager is enabled.
return mTelephonyMgr.getMultiSimConfiguration() != UNKNOWN && mEuiccManager.isEnabled();
} }
private void update() { private void update() {
if (mPreference == null) { if (mPreference == null) {
return; return;
} }
final boolean enableAddButton = shouldEnableAddButton(); final boolean showAddButton = shouldShowAddButton();
refreshSummary(mPreference); refreshSummary(mPreference);
if (!enableAddButton) { if (!showAddButton) {
mPreference.setOnAddClickListener(null); mPreference.setOnAddClickListener(null);
} else { } else {
mPreference.setAddWidgetEnabled(!mChangeListener.isAirplaneModeOn());
mPreference.setOnAddClickListener(p -> { mPreference.setOnAddClickListener(p -> {
startAddSimFlow(); startAddSimFlow();
}); });
@@ -134,11 +143,11 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
mSubscriptionManager); mSubscriptionManager);
mPreference.setOnPreferenceClickListener(null); mPreference.setOnPreferenceClickListener(null);
mPreference.setFragment(null); mPreference.setFragment(null);
mPreference.setEnabled(true); mPreference.setEnabled(!mChangeListener.isAirplaneModeOn());
if (subs.isEmpty()) { if (subs.isEmpty()) {
if (enableAddButton) { if (showAddButton) {
mPreference.setEnabled(false); mPreference.setEnabled(false);
} else { } else if (mEuiccManager.isEnabled()) {
mPreference.setOnPreferenceClickListener((Preference pref) -> { mPreference.setOnPreferenceClickListener((Preference pref) -> {
startAddSimFlow(); startAddSimFlow();
return true; return true;
@@ -157,7 +166,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
@Override @Override
public boolean isAvailable() { public boolean isAvailable() {
return true; return !Utils.isWifiOnly(mContext);
} }
@Override @Override
@@ -167,6 +176,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
@Override @Override
public void onAirplaneModeChanged(boolean airplaneModeEnabled) { public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
update();
} }
@Override @Override

View File

@@ -34,6 +34,7 @@ public class AddPreference extends RestrictedPreference implements View.OnClickL
private OnAddClickListener mListener; private OnAddClickListener mListener;
private View mWidgetFrame; private View mWidgetFrame;
private View mAddWidget;
public AddPreference(Context context, AttributeSet attrs) { public AddPreference(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@@ -53,6 +54,12 @@ public class AddPreference extends RestrictedPreference implements View.OnClickL
} }
} }
public void setAddWidgetEnabled(boolean enabled) {
if (mAddWidget != null) {
mAddWidget.setEnabled(enabled);
}
}
@Override @Override
protected int getSecondTargetResId() { protected int getSecondTargetResId() {
return R.layout.preference_widget_add; return R.layout.preference_widget_add;
@@ -67,9 +74,9 @@ public class AddPreference extends RestrictedPreference implements View.OnClickL
public void onBindViewHolder(PreferenceViewHolder holder) { public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder); super.onBindViewHolder(holder);
mWidgetFrame = holder.findViewById(android.R.id.widget_frame); mWidgetFrame = holder.findViewById(android.R.id.widget_frame);
final View addWidget = holder.findViewById(getAddWidgetResId()); mAddWidget = holder.findViewById(getAddWidgetResId());
addWidget.setEnabled(true); mAddWidget.setEnabled(true);
addWidget.setOnClickListener(this); mAddWidget.setOnClickListener(this);
} }
@Override @Override

View File

@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
@@ -33,9 +34,12 @@ import static org.mockito.Mockito.when;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.ConnectivityManager;
import android.provider.Settings;
import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager; import android.telephony.euicc.EuiccManager;
import android.text.TextUtils;
import com.android.settings.network.telephony.MobileNetworkActivity; import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settings.widget.AddPreference; import com.android.settings.widget.AddPreference;
@@ -61,7 +65,8 @@ public class MobileNetworkSummaryControllerTest {
private Lifecycle mLifecycle; private Lifecycle mLifecycle;
@Mock @Mock
private TelephonyManager mTelephonyManager; private TelephonyManager mTelephonyManager;
@Mock
private EuiccManager mEuiccManager;
@Mock @Mock
private PreferenceScreen mPreferenceScreen; private PreferenceScreen mPreferenceScreen;
@@ -74,7 +79,9 @@ public class MobileNetworkSummaryControllerTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext = spy(Robolectric.setupActivity(Activity.class)); mContext = spy(Robolectric.setupActivity(Activity.class));
when(mContext.getSystemService(eq(TelephonyManager.class))).thenReturn(mTelephonyManager); when(mContext.getSystemService(eq(TelephonyManager.class))).thenReturn(mTelephonyManager);
when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager);
when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(UNKNOWN); when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(UNKNOWN);
when(mEuiccManager.isEnabled()).thenReturn(true);
mController = new MobileNetworkSummaryController(mContext, mLifecycle); mController = new MobileNetworkSummaryController(mContext, mLifecycle);
mPreference = spy(new AddPreference(mContext, null)); mPreference = spy(new AddPreference(mContext, null));
@@ -88,6 +95,14 @@ public class MobileNetworkSummaryControllerTest {
SubscriptionUtil.setAvailableSubscriptionsForTesting(null); SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
} }
@Test
public void isAvailable_wifiOnlyMode_notAvailable() {
ConnectivityManager cm = mock(ConnectivityManager.class);
when(cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(cm);
assertThat(mController.isAvailable()).isFalse();
}
@Test @Test
public void getSummary_noSubscriptions_correctSummaryAndClickHandler() { public void getSummary_noSubscriptions_correctSummaryAndClickHandler() {
mController.displayPreference(mPreferenceScreen); mController.displayPreference(mPreferenceScreen);
@@ -101,6 +116,14 @@ public class MobileNetworkSummaryControllerTest {
EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION); EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION);
} }
@Test
public void getSummary_noSubscriptionsNoEuiccMgr_correctSummaryAndClickHandler() {
when(mEuiccManager.isEnabled()).thenReturn(false);
assertThat(TextUtils.isEmpty(mController.getSummary())).isTrue();
assertThat(mPreference.getOnPreferenceClickListener()).isNull();
assertThat(mPreference.getFragment()).isNull();
}
@Test @Test
public void getSummary_oneSubscription_correctSummaryAndClickHandler() { public void getSummary_oneSubscription_correctSummaryAndClickHandler() {
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class); final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
@@ -204,6 +227,15 @@ public class MobileNetworkSummaryControllerTest {
verify(mPreference, never()).setOnAddClickListener(notNull()); verify(mPreference, never()).setOnAddClickListener(notNull());
} }
@Test
public void addButton_noSubscriptionsMultiSimModeNoEuiccMgr_noAddClickListener() {
when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
when(mEuiccManager.isEnabled()).thenReturn(false);
mController.displayPreference(mPreferenceScreen);
mController.onResume();
verify(mPreference, never()).setOnAddClickListener(notNull());
}
@Test @Test
public void addButton_noSubscriptionsMultiSimMode_hasAddClickListenerAndPrefDisabled() { public void addButton_noSubscriptionsMultiSimMode_hasAddClickListenerAndPrefDisabled() {
when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS); when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
@@ -236,4 +268,73 @@ public class MobileNetworkSummaryControllerTest {
verify(mPreference, never()).setOnAddClickListener(isNull()); verify(mPreference, never()).setOnAddClickListener(isNull());
verify(mPreference).setOnAddClickListener(notNull()); verify(mPreference).setOnAddClickListener(notNull());
} }
@Test
public void addButton_oneSubscriptionAirplaneModeTurnedOn_addButtonGetsDisabled() {
when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
mController.displayPreference(mPreferenceScreen);
mController.onResume();
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
mController.onAirplaneModeChanged(true);
ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(captor.capture());
assertThat(captor.getValue()).isFalse();
}
@Test
public void onResume_oneSubscriptionAirplaneMode_isDisabled() {
when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
mController.displayPreference(mPreferenceScreen);
mController.onResume();
assertThat(mPreference.isEnabled()).isFalse();
ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(captor.capture());
assertThat(captor.getValue()).isFalse();
}
@Test
public void onAirplaneModeChanged_oneSubscriptionAirplaneModeGetsTurnedOn_isDisabled() {
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
mController.displayPreference(mPreferenceScreen);
mController.onResume();
assertThat(mPreference.isEnabled()).isTrue();
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
mController.onAirplaneModeChanged(true);
assertThat(mPreference.isEnabled()).isFalse();
}
@Test
public void onAirplaneModeChanged_oneSubscriptionAirplaneModeGetsTurnedOff_isEnabled() {
when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
mController.displayPreference(mPreferenceScreen);
mController.onResume();
assertThat(mPreference.isEnabled()).isFalse();
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
mController.onAirplaneModeChanged(false);
assertThat(mPreference.isEnabled()).isTrue();
ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(eq(false));
verify(mPreference, atLeastOnce()).setAddWidgetEnabled(captor.capture());
assertThat(captor.getValue()).isTrue();
}
} }