Merge changes I7d98ab42,I8753e681 into rvc-dev
* changes: Report NR connected state to provide resolution of 5G NSA mode Attribute data usage to virtual RAT type for 5G non-standalone mode
This commit is contained in:
committed by
Android (Google) Code Review
commit
7368ed7d03
@@ -5178,6 +5178,12 @@ message DataUsageBytesTransfer {
|
|||||||
// record is combined across opportunistic data subscriptions.
|
// record is combined across opportunistic data subscriptions.
|
||||||
// See {@link SubscriptionManager#setOpportunistic}.
|
// See {@link SubscriptionManager#setOpportunistic}.
|
||||||
optional DataSubscriptionState opportunistic_data_sub = 10;
|
optional DataSubscriptionState opportunistic_data_sub = 10;
|
||||||
|
|
||||||
|
// Indicate whether NR is connected, server side could use this with RAT type to determine if
|
||||||
|
// the record is for 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.
|
||||||
|
optional bool is_nr_connected = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -87,6 +87,15 @@ public class NetworkTemplate implements Parcelable {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int NETWORK_TYPE_ALL = -1;
|
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) {
|
private static boolean isKnownMatchRule(final int rule) {
|
||||||
switch (rule) {
|
switch (rule) {
|
||||||
@@ -475,6 +484,9 @@ public class NetworkTemplate implements Parcelable {
|
|||||||
return TelephonyManager.NETWORK_TYPE_LTE;
|
return TelephonyManager.NETWORK_TYPE_LTE;
|
||||||
case TelephonyManager.NETWORK_TYPE_NR:
|
case TelephonyManager.NETWORK_TYPE_NR:
|
||||||
return 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:
|
default:
|
||||||
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
|
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,13 @@
|
|||||||
|
|
||||||
package com.android.server.net;
|
package com.android.server.net;
|
||||||
|
|
||||||
|
import static android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA;
|
||||||
import static android.net.NetworkTemplate.getCollapsedRatType;
|
import static android.net.NetworkTemplate.getCollapsedRatType;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.telephony.Annotation;
|
import android.telephony.Annotation;
|
||||||
|
import android.telephony.NetworkRegistrationInfo;
|
||||||
import android.telephony.PhoneStateListener;
|
import android.telephony.PhoneStateListener;
|
||||||
import android.telephony.ServiceState;
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
@@ -195,7 +197,18 @@ public class NetworkStatsSubscriptionsMonitor extends
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceStateChanged(@NonNull ServiceState ss) {
|
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);
|
final int collapsedRatType = getCollapsedRatType(networkType);
|
||||||
if (collapsedRatType == mLastCollapsedRatType) return;
|
if (collapsedRatType == mLastCollapsedRatType) return;
|
||||||
|
|
||||||
|
|||||||
@@ -1145,6 +1145,15 @@ public class StatsPullAtomService extends SystemService {
|
|||||||
|
|
||||||
private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt,
|
private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt,
|
||||||
@NonNull List<StatsEvent> pulledData) {
|
@NonNull List<StatsEvent> pulledData) {
|
||||||
|
|
||||||
|
// Workaround for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}.
|
||||||
|
// 5G NSA mode means the primary cell is LTE with a secondary connection to an
|
||||||
|
// NR cell. To mitigate risk, NetworkStats is currently storing this state as
|
||||||
|
// a fake RAT type rather than storing the boolean separately.
|
||||||
|
final boolean is5GNsa = statsExt.ratType == NetworkTemplate.NETWORK_TYPE_5G_NSA;
|
||||||
|
// Report NR connected in 5G non-standalone mode, or if the RAT type is NR to begin with.
|
||||||
|
final boolean isNR = is5GNsa || statsExt.ratType == TelephonyManager.NETWORK_TYPE_NR;
|
||||||
|
|
||||||
final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
|
final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
|
||||||
for (int i = 0; i < statsExt.stats.size(); i++) {
|
for (int i = 0; i < statsExt.stats.size(); i++) {
|
||||||
statsExt.stats.getValues(i, entry);
|
statsExt.stats.getValues(i, entry);
|
||||||
@@ -1156,7 +1165,7 @@ public class StatsPullAtomService extends SystemService {
|
|||||||
.writeLong(entry.rxPackets)
|
.writeLong(entry.rxPackets)
|
||||||
.writeLong(entry.txBytes)
|
.writeLong(entry.txBytes)
|
||||||
.writeLong(entry.txPackets)
|
.writeLong(entry.txPackets)
|
||||||
.writeInt(statsExt.ratType)
|
.writeInt(is5GNsa ? TelephonyManager.NETWORK_TYPE_LTE : statsExt.ratType)
|
||||||
// Fill information about subscription, these cannot be null since invalid data
|
// Fill information about subscription, these cannot be null since invalid data
|
||||||
// would be filtered when adding into subInfo list.
|
// would be filtered when adding into subInfo list.
|
||||||
.writeString(statsExt.subInfo.mcc)
|
.writeString(statsExt.subInfo.mcc)
|
||||||
@@ -1165,6 +1174,7 @@ public class StatsPullAtomService extends SystemService {
|
|||||||
.writeInt(statsExt.subInfo.isOpportunistic
|
.writeInt(statsExt.subInfo.isOpportunistic
|
||||||
? DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC
|
? DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC
|
||||||
: DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC)
|
: DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC)
|
||||||
|
.writeBoolean(isNR)
|
||||||
.build();
|
.build();
|
||||||
pulledData.add(e);
|
pulledData.add(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import android.net.NetworkStats.METERED_ALL
|
|||||||
import android.net.NetworkStats.ROAMING_ALL
|
import android.net.NetworkStats.ROAMING_ALL
|
||||||
import android.net.NetworkTemplate.MATCH_MOBILE
|
import android.net.NetworkTemplate.MATCH_MOBILE
|
||||||
import android.net.NetworkTemplate.MATCH_WIFI
|
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.NETWORK_TYPE_ALL
|
||||||
import android.net.NetworkTemplate.buildTemplateMobileWithRatType
|
import android.net.NetworkTemplate.buildTemplateMobileWithRatType
|
||||||
import android.telephony.TelephonyManager
|
import android.telephony.TelephonyManager
|
||||||
@@ -145,11 +146,13 @@ class NetworkTemplateTest {
|
|||||||
assertParcelSane(templateWifi, 8)
|
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
|
@Test
|
||||||
fun testNetworkTypeAll() {
|
fun testNetworkTypeConstants() {
|
||||||
for (ratType in TelephonyManager.getAllNetworkTypes()) {
|
for (ratType in TelephonyManager.getAllNetworkTypes()) {
|
||||||
assertNotEquals(NETWORK_TYPE_ALL, ratType)
|
assertNotEquals(NETWORK_TYPE_ALL, ratType)
|
||||||
|
assertNotEquals(NETWORK_TYPE_5G_NSA, ratType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.net;
|
package com.android.server.net;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.eq;
|
import static org.mockito.Mockito.eq;
|
||||||
@@ -29,7 +30,9 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.NetworkTemplate;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.telephony.NetworkRegistrationInfo;
|
||||||
import android.telephony.PhoneStateListener;
|
import android.telephony.PhoneStateListener;
|
||||||
import android.telephony.ServiceState;
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
@@ -61,7 +64,6 @@ public final class NetworkStatsSubscriptionsMonitorTest {
|
|||||||
private static final String TEST_IMSI3 = "466929999999999";
|
private static final String TEST_IMSI3 = "466929999999999";
|
||||||
|
|
||||||
@Mock private Context mContext;
|
@Mock private Context mContext;
|
||||||
@Mock private PhoneStateListener mPhoneStateListener;
|
|
||||||
@Mock private SubscriptionManager mSubscriptionManager;
|
@Mock private SubscriptionManager mSubscriptionManager;
|
||||||
@Mock private TelephonyManager mTelephonyManager;
|
@Mock private TelephonyManager mTelephonyManager;
|
||||||
@Mock private Delegate mDelegate;
|
@Mock private Delegate mDelegate;
|
||||||
@@ -215,4 +217,55 @@ public final class NetworkStatsSubscriptionsMonitorTest {
|
|||||||
verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
|
verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
|
||||||
assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user