Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 475dde51 authored by Antony Sargent's avatar Antony Sargent
Browse files

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
parent 12cec798
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.telephony.euicc.EuiccManager;
import com.android.settings.R;
import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settings.widget.AddPreference;
import com.android.settingslib.Utils;
import com.android.settingslib.core.AbstractPreferenceController;

import java.util.List;
@@ -50,6 +51,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
    private SubscriptionManager mSubscriptionManager;
    private SubscriptionsChangeListener mChangeListener;
    private TelephonyManager mTelephonyMgr;
    private EuiccManager mEuiccManager;
    private AddPreference mPreference;

    /**
@@ -71,6 +73,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
        super(context);
        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
        mTelephonyMgr = mContext.getSystemService(TelephonyManager.class);
        mEuiccManager = mContext.getSystemService(EuiccManager.class);
        mChangeListener = new SubscriptionsChangeListener(context, this);
        lifecycle.addObserver(this);
    }
@@ -97,7 +100,11 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
        final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(
                mSubscriptionManager);
        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) {
            return subs.get(0).getDisplayName();
        } else {
@@ -112,20 +119,22 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
        mContext.startActivity(intent);
    }

    private boolean shouldEnableAddButton() {
        // The add button should only show up if the device is in multi-sim mode.
        return mTelephonyMgr.getMultiSimConfiguration() != UNKNOWN;
    private boolean shouldShowAddButton() {
        // The add button should only show up if the device is in multi-sim mode and the eSIM
        // manager is enabled.
        return mTelephonyMgr.getMultiSimConfiguration() != UNKNOWN && mEuiccManager.isEnabled();
    }

    private void update() {
        if (mPreference == null) {
            return;
        }
        final boolean enableAddButton = shouldEnableAddButton();
        final boolean showAddButton = shouldShowAddButton();
        refreshSummary(mPreference);
        if (!enableAddButton) {
        if (!showAddButton) {
            mPreference.setOnAddClickListener(null);
        } else {
            mPreference.setAddWidgetEnabled(!mChangeListener.isAirplaneModeOn());
            mPreference.setOnAddClickListener(p -> {
                startAddSimFlow();
            });
@@ -134,11 +143,11 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
                mSubscriptionManager);
        mPreference.setOnPreferenceClickListener(null);
        mPreference.setFragment(null);
        mPreference.setEnabled(true);
        mPreference.setEnabled(!mChangeListener.isAirplaneModeOn());
        if (subs.isEmpty()) {
            if (enableAddButton) {
            if (showAddButton) {
                mPreference.setEnabled(false);
            } else {
            } else if (mEuiccManager.isEnabled()) {
                mPreference.setOnPreferenceClickListener((Preference pref) -> {
                    startAddSimFlow();
                    return true;
@@ -157,7 +166,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController

    @Override
    public boolean isAvailable() {
        return true;
        return !Utils.isWifiOnly(mContext);
    }

    @Override
@@ -167,6 +176,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController

    @Override
    public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
        update();
    }

    @Override
+10 −3
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ public class AddPreference extends RestrictedPreference implements View.OnClickL

    private OnAddClickListener mListener;
    private View mWidgetFrame;
    private View mAddWidget;

    public AddPreference(Context context, AttributeSet 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
    protected int getSecondTargetResId() {
        return R.layout.preference_widget_add;
@@ -67,9 +74,9 @@ public class AddPreference extends RestrictedPreference implements View.OnClickL
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        mWidgetFrame = holder.findViewById(android.R.id.widget_frame);
        final View addWidget = holder.findViewById(getAddWidgetResId());
        addWidget.setEnabled(true);
        addWidget.setOnClickListener(this);
        mAddWidget = holder.findViewById(getAddWidgetResId());
        mAddWidget.setEnabled(true);
        mAddWidget.setOnClickListener(this);
    }

    @Override
+102 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -33,9 +34,12 @@ import static org.mockito.Mockito.when;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import android.text.TextUtils;

import com.android.settings.network.telephony.MobileNetworkActivity;
import com.android.settings.widget.AddPreference;
@@ -61,7 +65,8 @@ public class MobileNetworkSummaryControllerTest {
    private Lifecycle mLifecycle;
    @Mock
    private TelephonyManager mTelephonyManager;

    @Mock
    private EuiccManager mEuiccManager;
    @Mock
    private PreferenceScreen mPreferenceScreen;

@@ -74,7 +79,9 @@ public class MobileNetworkSummaryControllerTest {
        MockitoAnnotations.initMocks(this);
        mContext = spy(Robolectric.setupActivity(Activity.class));
        when(mContext.getSystemService(eq(TelephonyManager.class))).thenReturn(mTelephonyManager);
        when(mContext.getSystemService(EuiccManager.class)).thenReturn(mEuiccManager);
        when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(UNKNOWN);
        when(mEuiccManager.isEnabled()).thenReturn(true);

        mController = new MobileNetworkSummaryController(mContext, mLifecycle);
        mPreference = spy(new AddPreference(mContext, null));
@@ -88,6 +95,14 @@ public class MobileNetworkSummaryControllerTest {
        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
    public void getSummary_noSubscriptions_correctSummaryAndClickHandler() {
        mController.displayPreference(mPreferenceScreen);
@@ -101,6 +116,14 @@ public class MobileNetworkSummaryControllerTest {
                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
    public void getSummary_oneSubscription_correctSummaryAndClickHandler() {
        final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
@@ -204,6 +227,15 @@ public class MobileNetworkSummaryControllerTest {
        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
    public void addButton_noSubscriptionsMultiSimMode_hasAddClickListenerAndPrefDisabled() {
        when(mTelephonyManager.getMultiSimConfiguration()).thenReturn(DSDS);
@@ -236,4 +268,73 @@ public class MobileNetworkSummaryControllerTest {
        verify(mPreference, never()).setOnAddClickListener(isNull());
        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();
    }
}