Loading core/java/android/net/NetworkTemplate.java +12 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,15 @@ public class NetworkTemplate implements Parcelable { * @hide */ public static final int NETWORK_TYPE_ALL = -1; /** * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along * with NR state as connected. This should not be overlapped with any of the * {@code TelephonyManager.NETWORK_TYPE_*} constants. * * @hide */ public static final int NETWORK_TYPE_5G_NSA = -2; private static boolean isKnownMatchRule(final int rule) { switch (rule) { Loading Loading @@ -475,6 +484,9 @@ public class NetworkTemplate implements Parcelable { return TelephonyManager.NETWORK_TYPE_LTE; case TelephonyManager.NETWORK_TYPE_NR: return TelephonyManager.NETWORK_TYPE_NR; // Virtual RAT type for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. case NetworkTemplate.NETWORK_TYPE_5G_NSA: return NetworkTemplate.NETWORK_TYPE_5G_NSA; default: return TelephonyManager.NETWORK_TYPE_UNKNOWN; } Loading services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java +14 −1 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.server.net; import static android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA; import static android.net.NetworkTemplate.getCollapsedRatType; import android.annotation.NonNull; import android.content.Context; import android.os.Looper; import android.telephony.Annotation; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; Loading Loading @@ -196,7 +198,18 @@ public class NetworkStatsSubscriptionsMonitor extends @Override public void onServiceStateChanged(@NonNull ServiceState ss) { final int networkType = ss.getDataNetworkType(); // In 5G SA (Stand Alone) mode, the primary cell itself will be 5G hence telephony // would report RAT = 5G_NR. // However, in 5G NSA (Non Stand Alone) mode, the primary cell is still LTE and // network allocates a secondary 5G cell so telephony reports RAT = LTE along with // NR state as connected. In such case, attributes the data usage to NR. // See b/160727498. final boolean is5GNsa = (ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE || ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA) && ss.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED; final int networkType = (is5GNsa ? NETWORK_TYPE_5G_NSA : ss.getDataNetworkType()); final int collapsedRatType = getCollapsedRatType(networkType); if (collapsedRatType == mLastCollapsedRatType) return; Loading tests/net/java/android/net/NetworkTemplateTest.kt +5 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.net.NetworkStats.METERED_ALL import android.net.NetworkStats.ROAMING_ALL import android.net.NetworkTemplate.MATCH_MOBILE import android.net.NetworkTemplate.MATCH_WIFI import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA import android.net.NetworkTemplate.NETWORK_TYPE_ALL import android.net.NetworkTemplate.buildTemplateMobileWithRatType import android.telephony.TelephonyManager Loading Loading @@ -145,11 +146,13 @@ class NetworkTemplateTest { assertParcelSane(templateWifi, 8) } // Verify NETWORK_TYPE_ALL does not conflict with TelephonyManager#NETWORK_TYPE_* constants. // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with // TelephonyManager#NETWORK_TYPE_* constants. @Test fun testNetworkTypeAll() { fun testNetworkTypeConstants() { for (ratType in TelephonyManager.getAllNetworkTypes()) { assertNotEquals(NETWORK_TYPE_ALL, ratType) assertNotEquals(NETWORK_TYPE_5G_NSA, ratType) } } } tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java +54 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.net; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; Loading @@ -30,7 +31,9 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.content.Context; import android.net.NetworkTemplate; import android.os.test.TestLooper; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; Loading Loading @@ -61,7 +64,6 @@ public final class NetworkStatsSubscriptionsMonitorTest { private static final String TEST_IMSI3 = "466929999999999"; @Mock private Context mContext; @Mock private PhoneStateListener mPhoneStateListener; @Mock private SubscriptionManager mSubscriptionManager; @Mock private TelephonyManager mTelephonyManager; @Mock private NetworkStatsSubscriptionsMonitor.Delegate mDelegate; Loading Loading @@ -215,4 +217,55 @@ public final class NetworkStatsSubscriptionsMonitorTest { verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); } @Test public void test5g() { mMonitor.start(); // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback // before changing RAT type. Also capture listener for later use. addTestSub(TEST_SUBID1, TEST_IMSI1); assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = ArgumentCaptor.forClass(RatTypeListener.class); verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), eq(PhoneStateListener.LISTEN_SERVICE_STATE)); final RatTypeListener listener = CollectionUtils .find(ratTypeListenerCaptor.getAllValues(), it -> it.getSubId() == TEST_SUBID1); assertNotNull(listener); // Set RAT type to 5G NSA (non-standalone) mode, verify the monitor outputs // NETWORK_TYPE_5G_NSA. final ServiceState serviceState = mock(ServiceState.class); when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); listener.onServiceStateChanged(serviceState); assertRatTypeChangedForSub(TEST_IMSI1, NetworkTemplate.NETWORK_TYPE_5G_NSA); reset(mDelegate); // Set RAT type to LTE without NR connected, the RAT type should be downgraded to LTE. when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); listener.onServiceStateChanged(serviceState); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE); reset(mDelegate); // Verify NR connected with other RAT type does not take effect. when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_UMTS); when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); listener.onServiceStateChanged(serviceState); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); reset(mDelegate); // Set RAT type to 5G standalone mode, the RAT type should be NR. setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, TelephonyManager.NETWORK_TYPE_NR); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); reset(mDelegate); // Set NR state to none in standalone mode does not change anything. when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_NR); when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); listener.onServiceStateChanged(serviceState); assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); } } Loading
core/java/android/net/NetworkTemplate.java +12 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,15 @@ public class NetworkTemplate implements Parcelable { * @hide */ public static final int NETWORK_TYPE_ALL = -1; /** * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along * with NR state as connected. This should not be overlapped with any of the * {@code TelephonyManager.NETWORK_TYPE_*} constants. * * @hide */ public static final int NETWORK_TYPE_5G_NSA = -2; private static boolean isKnownMatchRule(final int rule) { switch (rule) { Loading Loading @@ -475,6 +484,9 @@ public class NetworkTemplate implements Parcelable { return TelephonyManager.NETWORK_TYPE_LTE; case TelephonyManager.NETWORK_TYPE_NR: return TelephonyManager.NETWORK_TYPE_NR; // Virtual RAT type for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. case NetworkTemplate.NETWORK_TYPE_5G_NSA: return NetworkTemplate.NETWORK_TYPE_5G_NSA; default: return TelephonyManager.NETWORK_TYPE_UNKNOWN; } Loading
services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java +14 −1 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.server.net; import static android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA; import static android.net.NetworkTemplate.getCollapsedRatType; import android.annotation.NonNull; import android.content.Context; import android.os.Looper; import android.telephony.Annotation; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; Loading Loading @@ -196,7 +198,18 @@ public class NetworkStatsSubscriptionsMonitor extends @Override public void onServiceStateChanged(@NonNull ServiceState ss) { final int networkType = ss.getDataNetworkType(); // In 5G SA (Stand Alone) mode, the primary cell itself will be 5G hence telephony // would report RAT = 5G_NR. // However, in 5G NSA (Non Stand Alone) mode, the primary cell is still LTE and // network allocates a secondary 5G cell so telephony reports RAT = LTE along with // NR state as connected. In such case, attributes the data usage to NR. // See b/160727498. final boolean is5GNsa = (ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE || ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA) && ss.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED; final int networkType = (is5GNsa ? NETWORK_TYPE_5G_NSA : ss.getDataNetworkType()); final int collapsedRatType = getCollapsedRatType(networkType); if (collapsedRatType == mLastCollapsedRatType) return; Loading
tests/net/java/android/net/NetworkTemplateTest.kt +5 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.net.NetworkStats.METERED_ALL import android.net.NetworkStats.ROAMING_ALL import android.net.NetworkTemplate.MATCH_MOBILE import android.net.NetworkTemplate.MATCH_WIFI import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA import android.net.NetworkTemplate.NETWORK_TYPE_ALL import android.net.NetworkTemplate.buildTemplateMobileWithRatType import android.telephony.TelephonyManager Loading Loading @@ -145,11 +146,13 @@ class NetworkTemplateTest { assertParcelSane(templateWifi, 8) } // Verify NETWORK_TYPE_ALL does not conflict with TelephonyManager#NETWORK_TYPE_* constants. // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with // TelephonyManager#NETWORK_TYPE_* constants. @Test fun testNetworkTypeAll() { fun testNetworkTypeConstants() { for (ratType in TelephonyManager.getAllNetworkTypes()) { assertNotEquals(NETWORK_TYPE_ALL, ratType) assertNotEquals(NETWORK_TYPE_5G_NSA, ratType) } } }
tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java +54 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.net; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; Loading @@ -30,7 +31,9 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.content.Context; import android.net.NetworkTemplate; import android.os.test.TestLooper; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; Loading Loading @@ -61,7 +64,6 @@ public final class NetworkStatsSubscriptionsMonitorTest { private static final String TEST_IMSI3 = "466929999999999"; @Mock private Context mContext; @Mock private PhoneStateListener mPhoneStateListener; @Mock private SubscriptionManager mSubscriptionManager; @Mock private TelephonyManager mTelephonyManager; @Mock private NetworkStatsSubscriptionsMonitor.Delegate mDelegate; Loading Loading @@ -215,4 +217,55 @@ public final class NetworkStatsSubscriptionsMonitorTest { verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE)); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); } @Test public void test5g() { mMonitor.start(); // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback // before changing RAT type. Also capture listener for later use. addTestSub(TEST_SUBID1, TEST_IMSI1); assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN); final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor = ArgumentCaptor.forClass(RatTypeListener.class); verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(), eq(PhoneStateListener.LISTEN_SERVICE_STATE)); final RatTypeListener listener = CollectionUtils .find(ratTypeListenerCaptor.getAllValues(), it -> it.getSubId() == TEST_SUBID1); assertNotNull(listener); // Set RAT type to 5G NSA (non-standalone) mode, verify the monitor outputs // NETWORK_TYPE_5G_NSA. final ServiceState serviceState = mock(ServiceState.class); when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); listener.onServiceStateChanged(serviceState); assertRatTypeChangedForSub(TEST_IMSI1, NetworkTemplate.NETWORK_TYPE_5G_NSA); reset(mDelegate); // Set RAT type to LTE without NR connected, the RAT type should be downgraded to LTE. when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); listener.onServiceStateChanged(serviceState); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE); reset(mDelegate); // Verify NR connected with other RAT type does not take effect. when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_UMTS); when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED); listener.onServiceStateChanged(serviceState); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS); reset(mDelegate); // Set RAT type to 5G standalone mode, the RAT type should be NR. setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1, TelephonyManager.NETWORK_TYPE_NR); assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); reset(mDelegate); // Set NR state to none in standalone mode does not change anything. when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_NR); when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE); listener.onServiceStateChanged(serviceState); assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR); } }