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

Commit 3ca59af9 authored by Jack Yu's avatar Jack Yu
Browse files

Exclude default APN from unmetered bypassing check

Currently telephony will let unmetered APN type of
data setup no matter user enables or disables the data. This
creates confusion for users when default APN type (i.e. internet)
is unmetered. The user can still user interent even when data is
turned off.

Now exclude default APN type from unmetered bypassing check. Other
APN types (e.g. IMS) can still go through when data is off.

Test: Unit test + Manual
Fix: 152245363
Change-Id: If2cd5474ff356b3de0cc4e567eead4535c31c76a
parent 49bab605
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
import static android.telephony.TelephonyManager.NETWORK_TYPE_NR;
import static android.telephony.data.ApnSetting.PROTOCOL_IPV4V6;
import static android.telephony.data.ApnSetting.TYPE_DEFAULT;
import static android.telephony.data.ApnSetting.TYPE_IA;

import static com.android.internal.telephony.RILConstants.DATA_PROFILE_DEFAULT;
import static com.android.internal.telephony.RILConstants.DATA_PROFILE_INVALID;
@@ -1250,6 +1251,11 @@ public class DcTracker extends Handler {

        DataConnectionReasons reasons = new DataConnectionReasons();

        int requestApnType = 0;
        if (apnContext != null) {
            requestApnType = apnContext.getApnTypeBitmask();
        }

        // Step 1: Get all environment conditions.
        final boolean internalDataEnabled = mDataEnabledSettings.isInternalDataEnabled();
        boolean attachedState = mAttached.get();
@@ -1266,8 +1272,7 @@ public class DcTracker extends Handler {
                SubscriptionManager.getDefaultDataSubscriptionId());

        boolean isMeteredApnType = apnContext == null
                || ApnSettingUtils.isMeteredApnType(ApnSetting.getApnTypesBitmaskFromString(
                        apnContext.getApnType()) , mPhone);
                || ApnSettingUtils.isMeteredApnType(requestApnType, mPhone);

        PhoneConstants.State phoneState = PhoneConstants.State.IDLE;
        // Note this is explicitly not using mPhone.getState.  See b/19090488.
@@ -1283,7 +1288,7 @@ public class DcTracker extends Handler {

        // Step 2: Special handling for emergency APN.
        if (apnContext != null
                && apnContext.getApnType().equals(PhoneConstants.APN_TYPE_EMERGENCY)
                && requestApnType == ApnSetting.TYPE_EMERGENCY
                && apnContext.isConnectable()) {
            // If this is an emergency APN, as long as the APN is connectable, we
            // should allow it.
@@ -1301,8 +1306,8 @@ public class DcTracker extends Handler {

        // In legacy mode, if RAT is IWLAN then don't allow default/IA PDP at all.
        // Rest of APN types can be evaluated for remaining conditions.
        if ((apnContext != null && (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)
                || apnContext.getApnType().equals(PhoneConstants.APN_TYPE_IA)))
        if ((apnContext != null && requestApnType == TYPE_DEFAULT
                || requestApnType == TYPE_IA)
                && mPhone.getTransportManager().isInLegacyMode()
                && dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
            reasons.add(DataDisallowedReasonType.ON_IWLAN);
@@ -1353,7 +1358,7 @@ public class DcTracker extends Handler {
        }

        boolean isDataEnabled = apnContext == null ? mDataEnabledSettings.isDataEnabled()
                : mDataEnabledSettings.isDataEnabled(apnContext.getApnTypeBitmask());
                : mDataEnabledSettings.isDataEnabled(requestApnType);

        if (!isDataEnabled) {
            reasons.add(DataDisallowedReasonType.DATA_DISABLED);
@@ -1378,7 +1383,7 @@ public class DcTracker extends Handler {
            // Or if the data is on cellular, and the APN type is determined unmetered by the
            // configuration.
            } else if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
                    && !isMeteredApnType) {
                    && !isMeteredApnType && requestApnType != TYPE_DEFAULT) {
                reasons.add(DataAllowedReasonType.UNMETERED_APN);
            }

+39 −2
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -1040,6 +1041,8 @@ public class DcTrackerTest extends TelephonyTest {

    private void initApns(String targetApn, String[] canHandleTypes) {
        doReturn(targetApn).when(mApnContext).getApnType();
        doReturn(ApnSetting.getApnTypesBitmaskFromString(mApnContext.getApnType()))
                .when(mApnContext).getApnTypeBitmask();
        doReturn(true).when(mApnContext).isConnectable();
        ApnSetting apnSetting = createApnSetting(ApnSetting.getApnTypesBitmaskFromString(
                TextUtils.join(",", canHandleTypes)));
@@ -1056,7 +1059,8 @@ public class DcTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testTrySetupDataEmergencyApn() throws Exception {
        initApns(PhoneConstants.APN_TYPE_EMERGENCY, new String[]{PhoneConstants.APN_TYPE_ALL});
        initApns(PhoneConstants.APN_TYPE_EMERGENCY,
                new String[]{PhoneConstants.APN_TYPE_EMERGENCY});
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, mApnContext));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

@@ -1071,7 +1075,7 @@ public class DcTrackerTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testTrySetupDataXcapApn() throws Exception {
        initApns(PhoneConstants.APN_TYPE_XCAP, new String[]{PhoneConstants.APN_TYPE_ALL});
        initApns(PhoneConstants.APN_TYPE_XCAP, new String[]{PhoneConstants.APN_TYPE_XCAP});

        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
@@ -1145,6 +1149,39 @@ public class DcTrackerTest extends TelephonyTest {
                any(Message.class));
    }

    // Test the unmetered default APN setup when data is disabled. Default APN should always honor
    // the users's setting.
    @Test
    @SmallTest
    public void testTrySetupDataUnmeteredDefaultDataDisabled() throws Exception {
        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
        //mDct.setUserDataEnabled(false);
        doReturn(false).when(mDataEnabledSettings).isDataEnabled();
        doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());

        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                new String[]{PhoneConstants.APN_TYPE_MMS});

        logd("Sending EVENT_CARRIER_CONFIG_CHANGED");
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_CARRIER_CONFIG_CHANGED, 1, 0));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, mApnContext));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        waitForMs(200);

        verify(mSimulatedCommandsVerifier, never()).setupDataCall(
                eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
                eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                any(Message.class));
    }


    // Test the metered APN setup when data is disabled.
    @Test
    @SmallTest