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

Commit c60a4447 authored by Sarah Chin's avatar Sarah Chin Committed by Gerrit Code Review
Browse files

Merge "Check for timers when checking isCampedOn5G"

parents eedfca0c b93f22fe
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -69,6 +69,14 @@ public class DisplayInfoController extends Handler {
        }
    }

    /**
     * @return True if either the primary or secondary 5G hysteresis timer is active,
     * and false if neither are.
     */
    public boolean is5GHysteresisActive() {
        return mNetworkTypeController.is5GHysteresisActive();
    }

    /**
     * Register for TelephonyDisplayInfo changed.
     * @param h Handler to notify
+8 −0
Original line number Diff line number Diff line
@@ -172,6 +172,14 @@ public class NetworkTypeController extends StateMachine {
        return mOverrideNetworkType;
    }

    /**
     * @return True if either the primary or secondary 5G hysteresis timer is active,
     * and false if neither are.
     */
    public boolean is5GHysteresisActive() {
        return mIsPrimaryTimerActive || mIsSecondaryTimerActive;
    }

    private void registerForAllEvents() {
        mPhone.registerForRadioOffOrNotAvailable(getHandler(),
                EVENT_RADIO_OFF_OR_UNAVAILABLE, null);
+2 −82
Original line number Diff line number Diff line
@@ -49,14 +49,12 @@ import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetworkType;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
import android.telephony.DataFailCause;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
@@ -109,7 +107,6 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@@ -1557,60 +1554,6 @@ public class DataConnection extends StateMachine {
        return true;
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean isDevice5GCapable() {
        return (mPhone.getRadioAccessFamily() & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0;
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean isTempNotMeteredSupportedByCarrier() {
        CarrierConfigManager configManager =
                mPhone.getContext().getSystemService(CarrierConfigManager.class);
        if (configManager != null) {
            PersistableBundle bundle = configManager.getConfigForSubId(mSubId);
            if (bundle != null) {
                return bundle.getBoolean(
                        CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL);
            }
        }

        return false;
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean isCampedOn5G() {
        TelephonyDisplayInfo displayInfo = mPhone.getDisplayInfoController()
                .getTelephonyDisplayInfo();
        int overrideNetworkType = displayInfo.getOverrideNetworkType();
        NetworkRegistrationInfo nri =  mPhone.getServiceState().getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        int networkType = nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
                : nri.getAccessNetworkTechnology();
        return networkType == TelephonyManager.NETWORK_TYPE_NR
                || ((networkType == TelephonyManager.NETWORK_TYPE_LTE
                || networkType == TelephonyManager.NETWORK_TYPE_LTE_CA)
                && (overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA
                || overrideNetworkType
                == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE));
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean tempNotMeteredPossible() {
        return isDevice5GCapable() && isTempNotMeteredSupportedByCarrier() && isCampedOn5G();
    }

    /**
     * Get the network capabilities for this data connection.
     *
@@ -1721,31 +1664,8 @@ public class DataConnection extends StateMachine {
                !mPhone.getServiceState().getDataRoaming());

        result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED, !mCongestedOverride);
        //result.setCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
        //        mUnmeteredOverride);

        // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
        // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
        // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few
        // devices and carriers.
        if (tempNotMeteredPossible()) {
        result.setCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
                mUnmeteredOverride);
        } else if (mUnmeteredOverride) {
            // If temp not metered is not possible, but mUnmeteredOverride got set, that means we
            // hit the bug.
            SubscriptionManager subscriptionManager = mPhone.getContext()
                    .getSystemService(SubscriptionManager.class);
            String message = "Unexpected temp not metered detected. carrier supported="
                    + isTempNotMeteredSupportedByCarrier() + ", device 5G capable="
                    + isDevice5GCapable() + ", display info="
                    + mPhone.getDisplayInfoController().getTelephonyDisplayInfo()
                    + ", subscription plans=" + subscriptionManager.getSubscriptionPlans(mSubId)
                    + ", Service state=" + mPhone.getServiceState();
            loge(message);
            AnomalyReporter.reportAnomaly(
                    UUID.fromString("9151f0fc-01df-4afb-b744-9c4529055249"), message);
        }

        result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED, !mIsSuspended);
        result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
+81 −2
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.NetworkType;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.DataFailCause;
@@ -136,6 +137,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -4189,9 +4191,28 @@ public class DcTracker extends Handler {
    }

    private void setDataConnectionUnmetered(boolean isUnmetered) {
        // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
        // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
        // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few
        // devices and carriers.
        if (!isUnmetered || (isUnmetered && tempNotMeteredPossible())) {
            for (DataConnection dataConnection : mDataConnections.values()) {
                dataConnection.onMeterednessChanged(isUnmetered);
            }
        } else {
            // isUnmetered=true but TEMP_NOT_METERED is not possible
            String message = "Unexpected temp not metered detected. carrier supported="
                    + isTempNotMeteredSupportedByCarrier() + ", device 5G capable="
                    + isDevice5GCapable() + ", camped on 5G=" + isCampedOn5G()
                    + ", timer active=" + mPhone.getDisplayInfoController().is5GHysteresisActive()
                    + ", display info="
                    + mPhone.getDisplayInfoController().getTelephonyDisplayInfo()
                    + ", subscription plans=" + mSubscriptionPlans
                    + ", Service state=" + mPhone.getServiceState();
            loge(message);
            AnomalyReporter.reportAnomaly(
                    UUID.fromString("9151f0fc-01df-4afb-b744-9c4529055250"), message);
        }
    }

    private boolean isNetworkTypeUnmetered(@NetworkType int networkType) {
@@ -4312,6 +4333,64 @@ public class DcTracker extends Handler {
        return false;
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean isDevice5GCapable() {
        return (mPhone.getRadioAccessFamily() & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0;
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean isTempNotMeteredSupportedByCarrier() {
        CarrierConfigManager configManager =
                mPhone.getContext().getSystemService(CarrierConfigManager.class);
        if (configManager != null) {
            PersistableBundle bundle = configManager.getConfigForSubId(mPhone.getSubId());
            if (bundle != null) {
                return bundle.getBoolean(
                        CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL);
            }
        }

        return false;
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean isCampedOn5G() {
        TelephonyDisplayInfo displayInfo = mPhone.getDisplayInfoController()
                .getTelephonyDisplayInfo();
        int overrideNetworkType = displayInfo.getOverrideNetworkType();
        NetworkRegistrationInfo nri =  mPhone.getServiceState().getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        int networkType = nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
                : nri.getAccessNetworkTechnology();

        boolean isNrSa = networkType == TelephonyManager.NETWORK_TYPE_NR;
        boolean isNrNsa = (networkType == TelephonyManager.NETWORK_TYPE_LTE
                || networkType == TelephonyManager.NETWORK_TYPE_LTE_CA)
                && (overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA
                || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE);
        boolean is5GHysteresisActive = mPhone.getDisplayInfoController().is5GHysteresisActive();

        // True if device is on NR SA or NR NSA, or neither but 5G hysteresis is active
        return isNrSa || isNrNsa || is5GHysteresisActive;
    }

    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
    // and carriers.
    private boolean tempNotMeteredPossible() {
        return isDevice5GCapable() && isTempNotMeteredSupportedByCarrier() && isCampedOn5G();
    }

    protected void log(String s) {
        Rlog.d(mLogTag, s);
    }
+24 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.internal.telephony;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;

@@ -392,6 +394,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // timer expires
        moveTimeForward(10 * 1000);
@@ -400,6 +403,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -422,6 +426,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // reconnect to NR in the middle of the timer
        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
@@ -435,6 +440,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -455,10 +461,10 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
        processAllMessages();


        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // timer expires
        moveTimeForward(10 * 1000);
@@ -467,6 +473,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -490,6 +497,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // reconnect to NR in the middle of the timer
        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
@@ -503,6 +511,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected_mmwave", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -527,6 +536,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // primary timer expires
        moveTimeForward(10 * 1000);
@@ -536,6 +546,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // secondary timer expires
        moveTimeForward(30 * 1000);
@@ -544,6 +555,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -568,6 +580,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // primary timer expires
        moveTimeForward(10 * 1000);
@@ -577,6 +590,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // reconnect to NR in the middle of the timer
        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
@@ -590,6 +604,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -615,6 +630,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // primary timer expires
        moveTimeForward(10 * 1000);
@@ -624,6 +640,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // secondary timer expires
        moveTimeForward(30 * 1000);
@@ -632,6 +649,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -657,6 +675,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // primary timer expires
        moveTimeForward(10 * 1000);
@@ -666,6 +685,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // reconnect to NR in the middle of the timer
        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
@@ -679,6 +699,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected_mmwave", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }

    @Test
@@ -704,6 +725,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("connected", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
                mNetworkTypeController.getOverrideNetworkType());
        assertTrue(mNetworkTypeController.is5GHysteresisActive());

        // rat is UMTS, should stop timer
        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getDataNetworkType();
@@ -714,5 +736,6 @@ public class NetworkTypeControllerTest extends TelephonyTest {
        assertEquals("legacy", getCurrentState().getName());
        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
                mNetworkTypeController.getOverrideNetworkType());
        assertFalse(mNetworkTypeController.is5GHysteresisActive());
    }
}
Loading