[ST01] Attributes data usage of test network by specifier
Currently, data usage of all test networks are all attributed to
the same NetworkIdentity, which does not allow services to
distinguish upload & download traffic of different test networks.
Thus, this CL put specifier that comes along with
TestNetworkAgent into wifiNetworkKey field to build different
NetworkIdentity to attribute data usage to different for
individual networks. And allow querying test network usage with
wifiNetworkKeys.
Bug: 139774492
Test: atest FrameworksNetTests
atest android.net.cts.ConnectivityManagerTest
Change-Id: I1bb38fd20781eaf3105735440a04b27bef36fcae
This commit is contained in:
@@ -85,6 +85,12 @@ public class NetworkIdentity {
|
|||||||
|
|
||||||
private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE;
|
private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE;
|
||||||
|
|
||||||
|
// Need to be synchronized with ConnectivityManager.
|
||||||
|
// TODO: Use {@code ConnectivityManager#*} when visible.
|
||||||
|
static final int TYPE_TEST = 18;
|
||||||
|
private static final int MAX_NETWORK_TYPE = TYPE_TEST;
|
||||||
|
private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
|
||||||
|
|
||||||
final int mType;
|
final int mType;
|
||||||
final int mRatType;
|
final int mRatType;
|
||||||
final int mSubId;
|
final int mSubId;
|
||||||
@@ -346,11 +352,6 @@ public class NetworkIdentity {
|
|||||||
* Builder class for {@link NetworkIdentity}.
|
* Builder class for {@link NetworkIdentity}.
|
||||||
*/
|
*/
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
// Need to be synchronized with ConnectivityManager.
|
|
||||||
// TODO: Use {@link ConnectivityManager#MAX_NETWORK_TYPE} when this file is in the module.
|
|
||||||
private static final int MAX_NETWORK_TYPE = 18; // TYPE_TEST
|
|
||||||
private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
|
|
||||||
|
|
||||||
private int mType;
|
private int mType;
|
||||||
private int mRatType;
|
private int mRatType;
|
||||||
private String mSubscriberId;
|
private String mSubscriberId;
|
||||||
@@ -413,6 +414,12 @@ public class NetworkIdentity {
|
|||||||
final WifiInfo info = (WifiInfo) transportInfo;
|
final WifiInfo info = (WifiInfo) transportInfo;
|
||||||
setWifiNetworkKey(info.getNetworkKey());
|
setWifiNetworkKey(info.getNetworkKey());
|
||||||
}
|
}
|
||||||
|
} else if (mType == TYPE_TEST) {
|
||||||
|
final NetworkSpecifier ns = snapshot.getNetworkCapabilities().getNetworkSpecifier();
|
||||||
|
if (ns instanceof TestNetworkSpecifier) {
|
||||||
|
// Reuse the wifi network key field to identify individual test networks.
|
||||||
|
setWifiNetworkKey(((TestNetworkSpecifier) ns).getInterfaceName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -574,7 +581,7 @@ public class NetworkIdentity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Assert non-wifi network cannot have a wifi network key.
|
// Assert non-wifi network cannot have a wifi network key.
|
||||||
if (mType != TYPE_WIFI && mWifiNetworkKey != null) {
|
if (mType != TYPE_WIFI && mType != TYPE_TEST && mWifiNetworkKey != null) {
|
||||||
throw new IllegalArgumentException("Invalid wifi network key for type " + mType);
|
throw new IllegalArgumentException("Invalid wifi network key for type " + mType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import android.os.Parcelable;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.net.module.util.CollectionUtils;
|
import com.android.net.module.util.CollectionUtils;
|
||||||
import com.android.net.module.util.NetworkIdentityUtils;
|
import com.android.net.module.util.NetworkIdentityUtils;
|
||||||
import com.android.net.module.util.NetworkStatsUtils;
|
import com.android.net.module.util.NetworkStatsUtils;
|
||||||
@@ -114,6 +115,14 @@ public final class NetworkTemplate implements Parcelable {
|
|||||||
* may offer non-cellular networks like WiFi, which will be matched by this rule.
|
* may offer non-cellular networks like WiFi, which will be matched by this rule.
|
||||||
*/
|
*/
|
||||||
public static final int MATCH_CARRIER = 10;
|
public static final int MATCH_CARRIER = 10;
|
||||||
|
/**
|
||||||
|
* Match rule to match networks with {@link ConnectivityManager#TYPE_TEST} as the legacy
|
||||||
|
* network type.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public static final int MATCH_TEST = 11;
|
||||||
|
|
||||||
// TODO: Remove this and replace all callers with WIFI_NETWORK_KEY_ALL.
|
// TODO: Remove this and replace all callers with WIFI_NETWORK_KEY_ALL.
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -176,6 +185,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||||||
case MATCH_BLUETOOTH:
|
case MATCH_BLUETOOTH:
|
||||||
case MATCH_PROXY:
|
case MATCH_PROXY:
|
||||||
case MATCH_CARRIER:
|
case MATCH_CARRIER:
|
||||||
|
case MATCH_TEST:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -666,6 +676,8 @@ public final class NetworkTemplate implements Parcelable {
|
|||||||
return matchesProxy(ident);
|
return matchesProxy(ident);
|
||||||
case MATCH_CARRIER:
|
case MATCH_CARRIER:
|
||||||
return matchesCarrier(ident);
|
return matchesCarrier(ident);
|
||||||
|
case MATCH_TEST:
|
||||||
|
return matchesTest(ident);
|
||||||
default:
|
default:
|
||||||
// We have no idea what kind of network template we are, so we
|
// We have no idea what kind of network template we are, so we
|
||||||
// just claim not to match anything.
|
// just claim not to match anything.
|
||||||
@@ -776,6 +788,17 @@ public final class NetworkTemplate implements Parcelable {
|
|||||||
&& CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
|
&& CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if matches test network. If the wifiNetworkKeys in the template is specified, Then it
|
||||||
|
* will only match a network containing any of the specified the wifi network key. Otherwise,
|
||||||
|
* all test networks would be matched.
|
||||||
|
*/
|
||||||
|
private boolean matchesTest(NetworkIdentity ident) {
|
||||||
|
return ident.mType == NetworkIdentity.TYPE_TEST
|
||||||
|
&& ((CollectionUtils.isEmpty(mMatchWifiNetworkKeys)
|
||||||
|
|| CollectionUtils.contains(mMatchWifiNetworkKeys, ident.mWifiNetworkKey)));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean matchesMobileWildcard(NetworkIdentity ident) {
|
private boolean matchesMobileWildcard(NetworkIdentity ident) {
|
||||||
if (ident.mType == TYPE_WIMAX) {
|
if (ident.mType == TYPE_WIMAX) {
|
||||||
return true;
|
return true;
|
||||||
@@ -829,6 +852,8 @@ public final class NetworkTemplate implements Parcelable {
|
|||||||
return "PROXY";
|
return "PROXY";
|
||||||
case MATCH_CARRIER:
|
case MATCH_CARRIER:
|
||||||
return "CARRIER";
|
return "CARRIER";
|
||||||
|
case MATCH_TEST:
|
||||||
|
return "TEST";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN(" + matchRule + ")";
|
return "UNKNOWN(" + matchRule + ")";
|
||||||
}
|
}
|
||||||
@@ -1079,7 +1104,9 @@ public final class NetworkTemplate implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateWifiNetworkKeys() {
|
private void validateWifiNetworkKeys() {
|
||||||
if (mMatchRule != MATCH_WIFI && !mMatchWifiNetworkKeys.isEmpty()) {
|
// Also allow querying test networks which use wifi network key as identifier.
|
||||||
|
if (mMatchRule != MATCH_WIFI && mMatchRule != MATCH_TEST
|
||||||
|
&& !mMatchWifiNetworkKeys.isEmpty()) {
|
||||||
throw new IllegalArgumentException("Trying to build non wifi match rule: "
|
throw new IllegalArgumentException("Trying to build non wifi match rule: "
|
||||||
+ mMatchRule + " with wifi network keys");
|
+ mMatchRule + " with wifi network keys");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1167,6 +1167,8 @@ public class ConnectivityManager {
|
|||||||
return "PROXY";
|
return "PROXY";
|
||||||
case TYPE_VPN:
|
case TYPE_VPN:
|
||||||
return "VPN";
|
return "VPN";
|
||||||
|
case TYPE_TEST:
|
||||||
|
return "TEST";
|
||||||
default:
|
default:
|
||||||
return Integer.toString(type);
|
return Integer.toString(type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ package android.net
|
|||||||
import android.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA
|
import android.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.ConnectivityManager.TYPE_MOBILE
|
import android.net.ConnectivityManager.TYPE_MOBILE
|
||||||
|
import android.net.ConnectivityManager.TYPE_TEST
|
||||||
import android.net.ConnectivityManager.TYPE_WIFI
|
import android.net.ConnectivityManager.TYPE_WIFI
|
||||||
|
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
||||||
|
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||||
import android.net.NetworkIdentity.OEM_NONE
|
import android.net.NetworkIdentity.OEM_NONE
|
||||||
import android.net.NetworkIdentity.OEM_PAID
|
import android.net.NetworkIdentity.OEM_PAID
|
||||||
import android.net.NetworkIdentity.OEM_PRIVATE
|
import android.net.NetworkIdentity.OEM_PRIVATE
|
||||||
@@ -31,6 +34,7 @@ import android.net.NetworkStats.METERED_YES
|
|||||||
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_MOBILE_WILDCARD
|
import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
|
||||||
|
import android.net.NetworkTemplate.MATCH_TEST
|
||||||
import android.net.NetworkTemplate.MATCH_WIFI
|
import android.net.NetworkTemplate.MATCH_WIFI
|
||||||
import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
|
import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
|
||||||
import android.net.NetworkTemplate.NETWORK_TYPE_ALL
|
import android.net.NetworkTemplate.NETWORK_TYPE_ALL
|
||||||
@@ -97,6 +101,14 @@ class NetworkTemplateTest {
|
|||||||
(oemManaged and OEM_PAID) == OEM_PAID)
|
(oemManaged and OEM_PAID) == OEM_PAID)
|
||||||
setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
|
setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
|
||||||
(oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
|
(oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
|
||||||
|
if (type == TYPE_TEST) {
|
||||||
|
wifiKey?.let { TestNetworkSpecifier(it) }?.let {
|
||||||
|
// Must have a single non-test transport specified to use setNetworkSpecifier.
|
||||||
|
// Put an arbitrary transport type which is not used in this test.
|
||||||
|
addTransportType(TRANSPORT_TEST)
|
||||||
|
addTransportType(TRANSPORT_WIFI)
|
||||||
|
setNetworkSpecifier(it) }
|
||||||
|
}
|
||||||
setTransportInfo(mockWifiInfo)
|
setTransportInfo(mockWifiInfo)
|
||||||
}
|
}
|
||||||
return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
|
return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
|
||||||
@@ -232,6 +244,32 @@ class NetworkTemplateTest {
|
|||||||
templateMobileNullImsiWithRatType.assertDoesNotMatch(identWifiImsi1Key1)
|
templateMobileNullImsiWithRatType.assertDoesNotMatch(identWifiImsi1Key1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTestNetworkTemplateMatches() {
|
||||||
|
val templateTestKey1 = NetworkTemplate.Builder(MATCH_TEST)
|
||||||
|
.setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
|
||||||
|
val templateTestKey2 = NetworkTemplate.Builder(MATCH_TEST)
|
||||||
|
.setWifiNetworkKeys(setOf(TEST_WIFI_KEY2)).build()
|
||||||
|
val templateTestAll = NetworkTemplate.Builder(MATCH_TEST).build()
|
||||||
|
|
||||||
|
val stateWifiKey1 = buildNetworkState(TYPE_WIFI, null /* subscriberId */, TEST_WIFI_KEY1,
|
||||||
|
OEM_NONE, true /* metered */)
|
||||||
|
val stateTestKey1 = buildNetworkState(TYPE_TEST, null /* subscriberId */, TEST_WIFI_KEY1,
|
||||||
|
OEM_NONE, true /* metered */)
|
||||||
|
val identWifi1 = buildNetworkIdentity(mockContext, stateWifiKey1,
|
||||||
|
false /* defaultNetwork */, NetworkTemplate.NETWORK_TYPE_ALL)
|
||||||
|
val identTest1 = buildNetworkIdentity(mockContext, stateTestKey1,
|
||||||
|
false /* defaultNetwork */, NETWORK_TYPE_ALL)
|
||||||
|
|
||||||
|
// Verify that the template matches corresponding type and the subscriberId.
|
||||||
|
templateTestKey1.assertDoesNotMatch(identWifi1)
|
||||||
|
templateTestKey1.assertMatches(identTest1)
|
||||||
|
templateTestKey2.assertDoesNotMatch(identWifi1)
|
||||||
|
templateTestKey2.assertDoesNotMatch(identTest1)
|
||||||
|
templateTestAll.assertDoesNotMatch(identWifi1)
|
||||||
|
templateTestAll.assertMatches(identTest1)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCarrierMeteredMatches() {
|
fun testCarrierMeteredMatches() {
|
||||||
val templateCarrierImsi1Metered = buildTemplateCarrierMetered(TEST_IMSI1)
|
val templateCarrierImsi1Metered = buildTemplateCarrierMetered(TEST_IMSI1)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static android.content.Intent.EXTRA_UID;
|
|||||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_TEST;
|
||||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.net.NetworkIdentity.OEM_PAID;
|
import static android.net.NetworkIdentity.OEM_PAID;
|
||||||
import static android.net.NetworkIdentity.OEM_PRIVATE;
|
import static android.net.NetworkIdentity.OEM_PRIVATE;
|
||||||
@@ -48,6 +49,7 @@ import static android.net.NetworkStats.TAG_NONE;
|
|||||||
import static android.net.NetworkStats.UID_ALL;
|
import static android.net.NetworkStats.UID_ALL;
|
||||||
import static android.net.NetworkStatsHistory.FIELD_ALL;
|
import static android.net.NetworkStatsHistory.FIELD_ALL;
|
||||||
import static android.net.NetworkTemplate.MATCH_MOBILE;
|
import static android.net.NetworkTemplate.MATCH_MOBILE;
|
||||||
|
import static android.net.NetworkTemplate.MATCH_TEST;
|
||||||
import static android.net.NetworkTemplate.MATCH_WIFI;
|
import static android.net.NetworkTemplate.MATCH_WIFI;
|
||||||
import static android.net.NetworkTemplate.OEM_MANAGED_NO;
|
import static android.net.NetworkTemplate.OEM_MANAGED_NO;
|
||||||
import static android.net.NetworkTemplate.OEM_MANAGED_YES;
|
import static android.net.NetworkTemplate.OEM_MANAGED_YES;
|
||||||
@@ -107,6 +109,7 @@ import android.net.NetworkStatsCollection;
|
|||||||
import android.net.NetworkStatsHistory;
|
import android.net.NetworkStatsHistory;
|
||||||
import android.net.NetworkTemplate;
|
import android.net.NetworkTemplate;
|
||||||
import android.net.TelephonyNetworkSpecifier;
|
import android.net.TelephonyNetworkSpecifier;
|
||||||
|
import android.net.TestNetworkSpecifier;
|
||||||
import android.net.TetherStatsParcel;
|
import android.net.TetherStatsParcel;
|
||||||
import android.net.TetheringManager;
|
import android.net.TetheringManager;
|
||||||
import android.net.UnderlyingNetworkInfo;
|
import android.net.UnderlyingNetworkInfo;
|
||||||
@@ -121,6 +124,7 @@ import android.os.SimpleClock;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.system.ErrnoException;
|
import android.system.ErrnoException;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
@@ -209,9 +213,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
private static final Network WIFI_NETWORK = new Network(100);
|
private static final Network WIFI_NETWORK = new Network(100);
|
||||||
private static final Network MOBILE_NETWORK = new Network(101);
|
private static final Network MOBILE_NETWORK = new Network(101);
|
||||||
private static final Network VPN_NETWORK = new Network(102);
|
private static final Network VPN_NETWORK = new Network(102);
|
||||||
|
private static final Network TEST_NETWORK = new Network(103);
|
||||||
|
|
||||||
private static final Network[] NETWORKS_WIFI = new Network[]{ WIFI_NETWORK };
|
private static final Network[] NETWORKS_WIFI = new Network[]{ WIFI_NETWORK };
|
||||||
private static final Network[] NETWORKS_MOBILE = new Network[]{ MOBILE_NETWORK };
|
private static final Network[] NETWORKS_MOBILE = new Network[]{ MOBILE_NETWORK };
|
||||||
|
private static final Network[] NETWORKS_TEST = new Network[]{ TEST_NETWORK };
|
||||||
|
|
||||||
private static final long WAIT_TIMEOUT = 2 * 1000; // 2 secs
|
private static final long WAIT_TIMEOUT = 2 * 1000; // 2 secs
|
||||||
private static final int INVALID_TYPE = -1;
|
private static final int INVALID_TYPE = -1;
|
||||||
@@ -817,7 +823,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
|
assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
|
||||||
assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
|
assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
|
||||||
|
|
||||||
|
|
||||||
// now pretend two UIDs are uninstalled, which should migrate stats to
|
// now pretend two UIDs are uninstalled, which should migrate stats to
|
||||||
// special "removed" bucket.
|
// special "removed" bucket.
|
||||||
mockDefaultSettings();
|
mockDefaultSettings();
|
||||||
@@ -940,8 +945,10 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
|
|
||||||
// Pretend that 5g mobile network comes online
|
// Pretend that 5g mobile network comes online
|
||||||
final NetworkStateSnapshot[] mobileStates =
|
final NetworkStateSnapshot[] mobileStates =
|
||||||
new NetworkStateSnapshot[] {buildMobileState(IMSI_1), buildMobileState(TEST_IFACE2,
|
new NetworkStateSnapshot[] {buildMobileState(IMSI_1), buildStateOfTransport(
|
||||||
IMSI_1, true /* isTemporarilyNotMetered */, false /* isRoaming */)};
|
NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
|
||||||
|
TEST_IFACE2, IMSI_1, null /* wifiNetworkKey */,
|
||||||
|
true /* isTemporarilyNotMetered */, false /* isRoaming */)};
|
||||||
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
|
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
|
||||||
mService.notifyNetworkStatus(NETWORKS_MOBILE, mobileStates,
|
mService.notifyNetworkStatus(NETWORKS_MOBILE, mobileStates,
|
||||||
getActiveIface(mobileStates), new UnderlyingNetworkInfo[0]);
|
getActiveIface(mobileStates), new UnderlyingNetworkInfo[0]);
|
||||||
@@ -1172,6 +1179,41 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
// already documented publicly, refer to {@link NetworkStatsManager#queryDetails}.
|
// already documented publicly, refer to {@link NetworkStatsManager#queryDetails}.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryTestNetworkUsage() throws Exception {
|
||||||
|
final NetworkTemplate templateTestAll = new NetworkTemplate.Builder(MATCH_TEST).build();
|
||||||
|
final NetworkTemplate templateTestIface1 = new NetworkTemplate.Builder(MATCH_TEST)
|
||||||
|
.setWifiNetworkKeys(Set.of(TEST_IFACE)).build();
|
||||||
|
final NetworkTemplate templateTestIface2 = new NetworkTemplate.Builder(MATCH_TEST)
|
||||||
|
.setWifiNetworkKeys(Set.of(TEST_IFACE2)).build();
|
||||||
|
// Test networks might use interface as subscriberId to identify individual networks.
|
||||||
|
// Simulate both cases.
|
||||||
|
final NetworkStateSnapshot[] states =
|
||||||
|
new NetworkStateSnapshot[]{buildTestState(TEST_IFACE, TEST_IFACE),
|
||||||
|
buildTestState(TEST_IFACE2, null /* wifiNetworkKey */)};
|
||||||
|
|
||||||
|
// Test networks comes online.
|
||||||
|
mockNetworkStatsSummary(buildEmptyStats());
|
||||||
|
mockNetworkStatsUidDetail(buildEmptyStats());
|
||||||
|
mService.notifyNetworkStatus(NETWORKS_TEST, states, getActiveIface(states),
|
||||||
|
new UnderlyingNetworkInfo[0]);
|
||||||
|
|
||||||
|
// Create some traffic on both interfaces.
|
||||||
|
incrementCurrentTime(MINUTE_IN_MILLIS);
|
||||||
|
mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
|
||||||
|
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
|
||||||
|
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L, 18L, 14L, 1L, 0L))
|
||||||
|
.addEntry(new NetworkStats.Entry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE,
|
||||||
|
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 7L, 3L, 5L, 1L, 1L)));
|
||||||
|
forcePollAndWaitForIdle();
|
||||||
|
|
||||||
|
// Verify test network templates gets stats. Stats of test networks without subscriberId
|
||||||
|
// can only be matched by templates without subscriberId requirement.
|
||||||
|
assertUidTotal(templateTestAll, UID_RED, 19L, 21L, 19L, 2L, 1);
|
||||||
|
assertUidTotal(templateTestIface1, UID_RED, 12L, 18L, 14L, 1L, 0);
|
||||||
|
assertUidTotal(templateTestIface2, UID_RED, 0L, 0L, 0L, 0L, 0);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUidStatsForTransport() throws Exception {
|
public void testUidStatsForTransport() throws Exception {
|
||||||
// pretend that network comes online
|
// pretend that network comes online
|
||||||
@@ -1319,7 +1361,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
// pretend that network comes online
|
// pretend that network comes online
|
||||||
mockDefaultSettings();
|
mockDefaultSettings();
|
||||||
NetworkStateSnapshot[] states =
|
NetworkStateSnapshot[] states =
|
||||||
new NetworkStateSnapshot[] {buildMobileState(TEST_IFACE, IMSI_1,
|
new NetworkStateSnapshot[] {buildStateOfTransport(
|
||||||
|
NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
|
||||||
|
TEST_IFACE, IMSI_1, null /* wifiNetworkKey */,
|
||||||
false /* isTemporarilyNotMetered */, true /* isRoaming */)};
|
false /* isTemporarilyNotMetered */, true /* isRoaming */)};
|
||||||
mockNetworkStatsSummary(buildEmptyStats());
|
mockNetworkStatsSummary(buildEmptyStats());
|
||||||
mockNetworkStatsUidDetail(buildEmptyStats());
|
mockNetworkStatsUidDetail(buildEmptyStats());
|
||||||
@@ -2189,24 +2233,34 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkStateSnapshot buildMobileState(String subscriberId) {
|
private static NetworkStateSnapshot buildMobileState(String subscriberId) {
|
||||||
return buildMobileState(TEST_IFACE, subscriberId, false /* isTemporarilyNotMetered */,
|
return buildStateOfTransport(NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
|
||||||
false /* isRoaming */);
|
TEST_IFACE, subscriberId, null /* wifiNetworkKey */,
|
||||||
|
false /* isTemporarilyNotMetered */, false /* isRoaming */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NetworkStateSnapshot buildMobileState(String iface, String subscriberId,
|
private static NetworkStateSnapshot buildTestState(@NonNull String iface,
|
||||||
|
@Nullable String wifiNetworkKey) {
|
||||||
|
return buildStateOfTransport(NetworkCapabilities.TRANSPORT_TEST, TYPE_TEST,
|
||||||
|
iface, null /* subscriberId */, wifiNetworkKey,
|
||||||
|
false /* isTemporarilyNotMetered */, false /* isRoaming */);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NetworkStateSnapshot buildStateOfTransport(int transport, int legacyType,
|
||||||
|
String iface, String subscriberId, String wifiNetworkKey,
|
||||||
boolean isTemporarilyNotMetered, boolean isRoaming) {
|
boolean isTemporarilyNotMetered, boolean isRoaming) {
|
||||||
final LinkProperties prop = new LinkProperties();
|
final LinkProperties prop = new LinkProperties();
|
||||||
prop.setInterfaceName(iface);
|
prop.setInterfaceName(iface);
|
||||||
final NetworkCapabilities capabilities = new NetworkCapabilities();
|
final NetworkCapabilities capabilities = new NetworkCapabilities();
|
||||||
|
|
||||||
if (isTemporarilyNotMetered) {
|
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
|
||||||
capabilities.addCapability(
|
isTemporarilyNotMetered);
|
||||||
NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
|
|
||||||
}
|
|
||||||
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
|
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
|
||||||
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
|
capabilities.addTransportType(transport);
|
||||||
|
if (legacyType == TYPE_TEST && !TextUtils.isEmpty(wifiNetworkKey)) {
|
||||||
|
capabilities.setNetworkSpecifier(new TestNetworkSpecifier(wifiNetworkKey));
|
||||||
|
}
|
||||||
return new NetworkStateSnapshot(
|
return new NetworkStateSnapshot(
|
||||||
MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE);
|
MOBILE_NETWORK, capabilities, prop, subscriberId, legacyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetworkStats buildEmptyStats() {
|
private NetworkStats buildEmptyStats() {
|
||||||
|
|||||||
Reference in New Issue
Block a user