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

Commit 46cff6bb authored by Jack Yu's avatar Jack Yu
Browse files

Fixed that data throttling was not properly enforced

The data retry time was not properly enforced since the
first version of Android. But since global retry (not limited
within one data setup request) and data unthrottling were
added in S, we should make sure no data setup request
is sent when the network explicitly asks the device not
to setup data connection within a certain period of time.

Fix: 184049035
Test: DcTrackerTest
Merged-In: Id354c362973181c25bee8fe26f0d680b05e49f19
Change-Id: Id354c362973181c25bee8fe26f0d680b05e49f19
(cherry picked from commit b0cb93e8)
parent 79d67fe7
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.telephony.dataconnection;

import com.android.internal.annotations.VisibleForTesting;

import java.util.HashSet;

/**
@@ -70,7 +72,14 @@ public class DataConnectionReasons {
        return mDataDisallowedReasonSet.size() == 0;
    }

    boolean contains(DataDisallowedReasonType reason) {
    /**
     * Check if it contains a certain disallowed reason.
     *
     * @param reason The disallowed reason to check.
     * @return {@code true} if the provided reason matches one of the disallowed reasons.
     */
    @VisibleForTesting
    public boolean contains(DataDisallowedReasonType reason) {
        return mDataDisallowedReasonSet.contains(reason);
    }

@@ -137,7 +146,10 @@ public class DataConnectionReasons {
        DATA_SERVICE_NOT_READY(true),
        // Qualified networks service does not allow certain types of APN brought up on either
        // cellular or IWLAN.
        DISABLED_BY_QNS(true);
        DISABLED_BY_QNS(true),
        // Data is throttled. The network explicitly requested device not to establish data
        // connection for a certain period.
        DATA_THROTTLED(true);

        private boolean mIsHardReason;

+6 −0
Original line number Diff line number Diff line
@@ -1457,6 +1457,12 @@ public class DcTracker extends Handler {
                    apnContext.getApnTypeBitmask()) && requestType != REQUEST_TYPE_HANDOVER) {
                reasons.add(DataDisallowedReasonType.ON_OTHER_TRANSPORT);
            }

            // Check if the device is under data throttling.
            long retryTime = mDataThrottler.getRetryTime(apnContext.getApnTypeBitmask());
            if (retryTime > SystemClock.elapsedRealtime()) {
                reasons.add(DataDisallowedReasonType.DATA_THROTTLED);
            }
        }

        boolean isDataEnabled = apnContext == null ? mDataEnabledSettings.isDataEnabled()
+32 −21
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.provider.Settings;
import android.provider.Telephony;
import android.telephony.AccessNetworkConstants;
@@ -97,6 +98,7 @@ import com.android.internal.telephony.ISub;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;

import org.junit.After;
import org.junit.Before;
@@ -800,18 +802,6 @@ public class DcTrackerTest extends TelephonyTest {
        assertEquals(FAKE_GATEWAY, linkProperties.getRoutes().get(0).getGateway().getHostAddress());
    }

    private boolean isDataAllowed(DataConnectionReasons dataConnectionReasons) {
        try {
            Method method = DcTracker.class.getDeclaredMethod("isDataAllowed",
                    DataConnectionReasons.class);
            method.setAccessible(true);
            return (boolean) method.invoke(mDct, dataConnectionReasons);
        } catch (Exception e) {
            fail(e.toString());
            return false;
        }
    }

    private boolean isHandoverPending(int apnType) {
        try {
            Method method = DcTracker.class.getDeclaredMethod("isHandoverPending",
@@ -881,7 +871,7 @@ public class DcTrackerTest extends TelephonyTest {
    @MediumTest
    public void testDataSetup() throws Exception {
        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
        boolean allowed = isDataAllowed(dataConnectionReasons);
        boolean allowed = mDct.isDataAllowed(dataConnectionReasons);
        assertFalse(dataConnectionReasons.toString(), allowed);

        logd("Sending EVENT_ENABLE_APN");
@@ -892,7 +882,7 @@ public class DcTrackerTest extends TelephonyTest {
        sendInitializationEvents();

        dataConnectionReasons = new DataConnectionReasons();
        allowed = isDataAllowed(dataConnectionReasons);
        allowed = mDct.isDataAllowed(dataConnectionReasons);
        assertTrue(dataConnectionReasons.toString(), allowed);

        ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
@@ -923,7 +913,7 @@ public class DcTrackerTest extends TelephonyTest {
        mSimulatedCommands.setDataCallResult(true, result);

        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
        boolean allowed = isDataAllowed(dataConnectionReasons);
        boolean allowed = mDct.isDataAllowed(dataConnectionReasons);
        assertFalse(dataConnectionReasons.toString(), allowed);

        logd("Sending EVENT_ENABLE_APN");
@@ -934,7 +924,7 @@ public class DcTrackerTest extends TelephonyTest {
        sendInitializationEvents();

        dataConnectionReasons = new DataConnectionReasons();
        allowed = isDataAllowed(dataConnectionReasons);
        allowed = mDct.isDataAllowed(dataConnectionReasons);
        assertTrue(dataConnectionReasons.toString(), allowed);

        ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
@@ -2734,7 +2724,7 @@ public class DcTrackerTest extends TelephonyTest {
    @Test
    public void testRatChanged() throws Exception {
        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
        boolean allowed = isDataAllowed(dataConnectionReasons);
        boolean allowed = mDct.isDataAllowed(dataConnectionReasons);
        assertFalse(dataConnectionReasons.toString(), allowed);

        logd("Sending EVENT_ENABLE_APN");
@@ -2744,7 +2734,7 @@ public class DcTrackerTest extends TelephonyTest {
        sendInitializationEvents();

        dataConnectionReasons = new DataConnectionReasons();
        allowed = isDataAllowed(dataConnectionReasons);
        allowed = mDct.isDataAllowed(dataConnectionReasons);
        assertTrue(dataConnectionReasons.toString(), allowed);

        ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
@@ -2872,15 +2862,15 @@ public class DcTrackerTest extends TelephonyTest {

    @Test
    public void testDataUnthrottled() throws Exception {
        DataThrottler mockedDataThrottler = Mockito.mock(DataThrottler.class);
        replaceInstance(DcTracker.class, "mDataThrottler", mDct, mockedDataThrottler);
        initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
        replaceInstance(DcTracker.class, "mDataThrottler", mDct, mDataThrottler);
        mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
        sendInitializationEvents();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_APN_UNTHROTTLED,
                new AsyncResult(null, FAKE_APN3, null)));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        verify(mockedDataThrottler).setRetryTime(
        verify(mDataThrottler).setRetryTime(
                eq(ApnSetting.TYPE_IMS),
                eq(RetryManager.NO_SUGGESTED_RETRY_DELAY),
                eq(DcTracker.REQUEST_TYPE_NORMAL));
@@ -2911,6 +2901,27 @@ public class DcTrackerTest extends TelephonyTest {
        assertTrue(msgs.get(ApnSetting.TYPE_IMS).contains(msg));
    }

    @Test
    public void testDataThrottledNotAllowData() throws Exception {
        initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
        replaceInstance(DcTracker.class, "mDataThrottler", mDct, mDataThrottler);
        doReturn(SystemClock.elapsedRealtime() + 100000).when(mDataThrottler)
                .getRetryTime(ApnSetting.TYPE_IMS);
        mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
        sendInitializationEvents();

        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
        boolean allowed = mDct.isDataAllowed(mApnContext, DcTracker.REQUEST_TYPE_NORMAL,
                dataConnectionReasons);
        assertFalse(dataConnectionReasons.toString(), allowed);
        assertTrue(dataConnectionReasons.contains(DataDisallowedReasonType.DATA_THROTTLED));

        // Makre sure no data setup request
        verify(mSimulatedCommandsVerifier, never()).setupDataCall(
                anyInt(), any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(),
                anyInt(), any(), any(), anyBoolean(), any(Message.class));
    }

    @Test
    public void testNotifyDataDisconnected() {
        // Verify notify data disconnected on DCT constructor, initialized in setUp()