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

Commit 4c5a29b5 authored by Sarah Chin's avatar Sarah Chin
Browse files

Support carrier config for sub6/mmwave unmetered

Fix error in putLong for int and update/add tests
Reset meteredness on screen off and reevaluate on screen on

Test: atest DcTrackerTest
Bug: 147312358
Bug: 149035138
Fixes: 148114683
Change-Id: I97ba1a1973153b69f16650380f58c239fac5edd9
Merged-In: I97ba1a1973153b69f16650380f58c239fac5edd9
parent fc294b1a
Loading
Loading
Loading
Loading
+35 −5
Original line number Diff line number Diff line
@@ -343,9 +343,14 @@ public class DcTracker extends Handler {
    private final LocalLog mApnSettingsInitializationLog = new LocalLog(50);

    /* Default for 5G connection reevaluation alarm durations */
    private long mHysteresisTimeMs = 0;
    private int mHysteresisTimeSec = 0;
    private long mWatchdogTimeMs = 1000 * 60 * 60;

    /* Default for whether 5G frequencies are considered unmetered */
    private boolean mAllUnmetered = false;
    private boolean mMmwaveUnmetered = false;
    private boolean mSub6Unmetered = false;

    /* Used to check whether 5G timers are currently active and waiting to go off */
    private boolean mHysteresis = false;
    private boolean mWatchdog = false;
@@ -373,12 +378,16 @@ public class DcTracker extends Handler {
                stopNetStatPoll();
                startNetStatPoll();
                restartDataStallAlarm();
                reevaluateUnmeteredConnections();
            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                if (DBG) log("screen off");
                mIsScreenOn = false;
                stopNetStatPoll();
                startNetStatPoll();
                restartDataStallAlarm();
                stopHysteresisAlarm();
                stopWatchdogAlarm();
                setDataConnectionUnmetered(false);
            } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
                onActionIntentDataStallAlarm(intent);
            } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
@@ -408,10 +417,16 @@ public class DcTracker extends Handler {
                            mDataIconPattern = CarrierConfigManager.getDefaultConfig().getString(
                                    CarrierConfigManager.KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING);
                        }
                        mHysteresisTimeMs = b.getLong(
                        mHysteresisTimeSec = b.getInt(
                                CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT);
                        mWatchdogTimeMs = b.getLong(
                                CarrierConfigManager.KEY_5G_WATCHDOG_TIME_MS_LONG);
                        mAllUnmetered = b.getBoolean(
                                CarrierConfigManager.KEY_UNMETERED_NR_NSA_BOOL);
                        mMmwaveUnmetered = b.getBoolean(
                                CarrierConfigManager.KEY_UNMETERED_NR_NSA_MMWAVE_BOOL);
                        mSub6Unmetered = b.getBoolean(
                                CarrierConfigManager.KEY_UNMETERED_NR_NSA_SUB6_BOOL);
                    }
                }
            } else {
@@ -4045,7 +4060,8 @@ public class DcTracker extends Handler {
    }

    private boolean reevaluateUnmeteredConnections() {
        if (isNetworkTypeUnmetered(NETWORK_TYPE_NR)) {
        if (isNetworkTypeUnmetered(NETWORK_TYPE_NR) || isFrequencyRangeUnmetered()) {
            if (DBG) log("NR NSA is unmetered");
            if (mPhone.getServiceState().getNrState()
                    == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
                if (!m5GWasConnected) { // 4G -> 5G
@@ -4125,6 +4141,20 @@ public class DcTracker extends Handler {
                || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED);
    }

    private boolean isFrequencyRangeUnmetered() {
        boolean nrConnected = mPhone.getServiceState().getNrState()
                == NetworkRegistrationInfo.NR_STATE_CONNECTED;
        if (mMmwaveUnmetered || mSub6Unmetered) {
            int frequencyRange = mPhone.getServiceState().getNrFrequencyRange();
            boolean mmwave = frequencyRange == ServiceState.FREQUENCY_RANGE_MMWAVE;
            // frequency range LOW, MID, or HIGH
            boolean sub6 = frequencyRange != ServiceState.FREQUENCY_RANGE_UNKNOWN && !mmwave;
            return (mMmwaveUnmetered && mmwave || mSub6Unmetered && sub6) && nrConnected;
        } else {
            return mAllUnmetered && nrConnected;
        }
    }

    private boolean updateDisplayInfo() {
        int displayNetworkType = DisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
        int dataNetworkType = mPhone.getServiceState().getDataNetworkType();
@@ -5052,10 +5082,10 @@ public class DcTracker extends Handler {
     * 5G connection reevaluation alarms
     */
    private boolean startHysteresisAlarm() {
        if (mHysteresisTimeMs > 0) {
        if (mHysteresisTimeSec > 0) {
            // only create hysteresis alarm if CarrierConfig allows it
            sendMessageDelayed(obtainMessage(DctConstants.EVENT_5G_TIMER_HYSTERESIS),
                    mHysteresisTimeMs);
                    mHysteresisTimeSec * 1000);
            mHysteresis = true;
            return true;
        } else {
+69 −9
Original line number Diff line number Diff line
@@ -1835,13 +1835,20 @@ public class DcTrackerTest extends TelephonyTest {
        return (boolean) method.invoke(mDct, networkType);
    }

    private void setUpDataConnection() throws Exception {
    private int setUpDataConnection() throws Exception {
        Field dc = DcTracker.class.getDeclaredField("mDataConnections");
        dc.setAccessible(true);
        Field uig = DcTracker.class.getDeclaredField("mUniqueIdGenerator");
        uig.setAccessible(true);
        ((HashMap<Integer, DataConnection>) dc.get(mDct)).put(
                ((AtomicInteger) uig.get(mDct)).getAndIncrement(), mDataConnection);
        int id = ((AtomicInteger) uig.get(mDct)).getAndIncrement();
        ((HashMap<Integer, DataConnection>) dc.get(mDct)).put(id, mDataConnection);
        return id;
    }

    private void resetDataConnection(int id) throws Exception {
        Field dc = DcTracker.class.getDeclaredField("mDataConnections");
        dc.setAccessible(true);
        ((HashMap<Integer, DataConnection>) dc.get(mDct)).remove(id);
    }

    private void setUpWatchdogTimer() {
@@ -1899,10 +1906,57 @@ public class DcTrackerTest extends TelephonyTest {
        assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
    }

    @Test
    public void testIsFrequencyRangeUnmetered() throws Exception {
        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
        int id = setUpDataConnection();
        setUpSubscriptionPlans(false);
        setUpWatchdogTimer();
        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();

        // NetCapability should be metered when connected to 5G with no unmetered plan or frequency
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        verify(mDataConnection, times(1)).onMeterednessChanged(false);

        // Set MMWAVE frequency to unmetered
        mBundle.putBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, true);
        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
        mContext.sendBroadcast(intent);
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        // NetCapability should switch to unmetered when fr=MMWAVE and MMWAVE unmetered
        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        verify(mDataConnection, times(1)).onMeterednessChanged(true);

        // NetCapability should switch to metered when fr=SUB6 and MMWAVE unmetered
        doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange();
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        verify(mDataConnection, times(2)).onMeterednessChanged(false);

        // Set SUB6 frequency to unmetered
        mBundle.putBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_SUB6_BOOL, true);
        intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
        mContext.sendBroadcast(intent);
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        // NetCapability should switch to unmetered when fr=SUB6 and SUB6 unmetered
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        verify(mDataConnection, times(2)).onMeterednessChanged(true);

        resetDataConnection(id);
    }

    @Test
    public void testReevaluateUnmeteredConnectionsOnNetworkChange() throws Exception {
        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
        setUpDataConnection();
        int id = setUpDataConnection();
        setUpSubscriptionPlans(true);
        setUpWatchdogTimer();

@@ -1917,17 +1971,19 @@ public class DcTrackerTest extends TelephonyTest {
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        verify(mDataConnection, times(1)).onMeterednessChanged(false);

        resetDataConnection(id);
    }

    @Test
    public void testReevaluateUnmeteredConnectionsOnHysteresis() throws Exception {
        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
        setUpDataConnection();
        int id = setUpDataConnection();
        setUpSubscriptionPlans(true);
        setUpWatchdogTimer();

        // Hysteresis active for 10s
        mBundle.putLong(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 10000);
        mBundle.putInt(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 10000);
        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
        mContext.sendBroadcast(intent);
@@ -1964,7 +2020,7 @@ public class DcTrackerTest extends TelephonyTest {
        assertFalse(getHysteresisStatus());

        // Hysteresis disabled
        mBundle.putLong(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0);
        mBundle.putInt(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0);
        intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
        mContext.sendBroadcast(intent);
@@ -1975,12 +2031,14 @@ public class DcTrackerTest extends TelephonyTest {
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        assertFalse(getHysteresisStatus());

        resetDataConnection(id);
    }

    @Test
    public void testReevaluateUnmeteredConnectionsOnWatchdog() throws Exception {
        initApns(PhoneConstants.APN_TYPE_DEFAULT, new String[]{PhoneConstants.APN_TYPE_ALL});
        setUpDataConnection();
        int id = setUpDataConnection();
        setUpSubscriptionPlans(true);
        setUpWatchdogTimer();

@@ -1991,7 +2049,7 @@ public class DcTrackerTest extends TelephonyTest {
        assertFalse(getWatchdogStatus());

        // Hysteresis active for 10s
        mBundle.putLong(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 10000);
        mBundle.putInt(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 10000);
        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
        mContext.sendBroadcast(intent);
@@ -2016,6 +2074,8 @@ public class DcTrackerTest extends TelephonyTest {
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SERVICE_STATE_CHANGED));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        assertFalse(getWatchdogStatus());

        resetDataConnection(id);
    }

    @Test