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

Commit ffd98d4d authored by Sarah Chin's avatar Sarah Chin Committed by Automerger Merge Worker
Browse files

Merge "Check for timers when checking isCampedOn5G" am: c60a4447

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1577964

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I9755d7d986840bc5556a7cf879ff4ae0727202d5
parents 61eaa25e c60a4447
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