[automerger skipped] DO NOT MERGE Add mock filegroups to deal with merge conflict problem am: dc72f289c1 -s ours
am skip reason: subject contains skip directive
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/16927065
Change-Id: I3097985bebe86b2f04ed417316c36b483404355a
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 302c0b3..a5b97a1 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -19,6 +19,9 @@
]
},
{
+ "name": "bpf_existence_test"
+ },
+ {
"name": "netd_updatable_unit_test"
},
{
@@ -32,16 +35,15 @@
},
{
"name": "libnetworkstats_test"
+ },
+ {
+ "name": "FrameworksNetIntegrationTests"
}
],
"postsubmit": [
{
"name": "TetheringPrivilegedTests"
},
- // TODO: move to presubmit when known green.
- {
- "name": "bpf_existence_test"
- },
{
"name": "netd_updatable_unit_test",
"keywords": ["netd-device-kernel-4.9", "netd-device-kernel-4.14"]
@@ -55,6 +57,9 @@
},
{
"name": "libnetworkstats_test"
+ },
+ {
+ "name": "FrameworksNetDeflakeTest"
}
],
"mainline-presubmit": [
@@ -70,6 +75,9 @@
]
},
{
+ "name": "bpf_existence_test[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
+ },
+ {
"name": "netd_updatable_unit_test[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
},
{
@@ -88,12 +96,57 @@
"name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]",
"keywords": ["sim"]
},
+ // TODO: move to mainline-presubmit when known green.
+ // Test with APK modules only, in cases where APEX is not supported, or the other modules were simply not updated
{
- "name": "TetheringCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
+ "name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk]",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.RequiresDevice"
+ },
+ {
+ "exclude-annotation": "com.android.testutils.ConnectivityModuleTest"
+ }
+ ]
},
// TODO: move to mainline-presubmit when known green.
+ // Test with connectivity/tethering module only, to catch integration issues with older versions of other modules.
+ // "new tethering + old NetworkStack" is not a configuration that should really exist in the field, but
+ // there is no strong guarantee, and it is required by MTS testing for module qualification, where modules
+ // are tested independently.
{
- "name": "bpf_existence_test[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
+ "name": "CtsNetTestCasesLatestSdk[com.google.android.tethering.apex]",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.RequiresDevice"
+ }
+ ]
+ },
+ {
+ "name": "TetheringCoverageTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
+ }
+ ],
+ "auto-postsubmit": [
+ // Test tag for automotive targets. These are only running in postsubmit so as to harden the
+ // automotive targets to avoid introducing additional test flake and build time. The plan for
+ // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
+ // Additionally, this tag is used in targeted test suites to limit resource usage on the test
+ // infra during the hardening phase.
+ // TODO: this tag to be removed once the above is no longer an issue.
+ {
+ "name": "FrameworksNetTests"
+ },
+ {
+ "name": "FrameworksNetIntegrationTests"
+ },
+ {
+ "name": "FrameworksNetDeflakeTest"
}
],
"imports": [
@@ -108,12 +161,6 @@
},
{
"path": "packages/modules/CaptivePortalLogin"
- },
- {
- "path": "packages/modules/Connectivity"
- },
- {
- "path": "packages/modules/Connectivity/Tethering"
}
]
}
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index 46fd50f..41a0651 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -50,6 +50,7 @@
],
libs: [
"framework-connectivity",
+ "framework-connectivity-t.stubs.module_lib",
"framework-statsd.stubs.module_lib",
"framework-tethering.impl",
"framework-wifi",
diff --git a/Tethering/AndroidManifest.xml b/Tethering/AndroidManifest.xml
index 6deb345..b832e16 100644
--- a/Tethering/AndroidManifest.xml
+++ b/Tethering/AndroidManifest.xml
@@ -41,6 +41,7 @@
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<protected-broadcast android:name="com.android.server.connectivity.tethering.DISABLE_TETHERING" />
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 4ccad22..2b70bcd 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -22,16 +22,16 @@
// different value depending on the branch.
java_defaults {
name: "ConnectivityNextEnableDefaults",
- enabled: false,
+ enabled: true,
}
apex_defaults {
name: "ConnectivityApexDefaults",
// Tethering app to include in the AOSP apex. Branches that disable the "next" targets may use
// a stable tethering app instead, but will generally override the AOSP apex to use updatable
// package names and keys, so that apex will be unused anyway.
- apps: ["Tethering"], // Replace to "Tethering" if ConnectivityNextEnableDefaults is false.
+ apps: ["TetheringNext"], // Replace to "Tethering" if ConnectivityNextEnableDefaults is false.
}
-enable_tethering_next_apex = false
+enable_tethering_next_apex = true
// This is a placeholder comment to avoid merge conflicts
// as the above target may have different "enabled" values
// depending on the branch
@@ -59,8 +59,7 @@
both: {
jni_libs: [
"libframework-connectivity-jni",
- // Changed in sc-mainline-prod only: no framework-connectivity-tiramisu
- // "libframework-connectivity-tiramisu-jni"
+ "libframework-connectivity-tiramisu-jni"
],
},
},
@@ -77,6 +76,7 @@
],
apps: [
"ServiceConnectivityResources",
+ "HalfSheetUX",
],
prebuilts: [
"current_sdkinfo",
@@ -107,7 +107,7 @@
name: "com.android.tethering-bootclasspath-fragment",
contents: [
"framework-connectivity",
- // Changed in sc-mainline-prod only: no framework-connectivity-tiramisu
+ "framework-connectivity-t",
"framework-tethering",
],
apex_available: ["com.android.tethering"],
@@ -130,18 +130,15 @@
// modified by the Soong or platform compat team.
hidden_api: {
max_target_r_low_priority: [
- // Changed in sc-mainline-prod only: no list for
- // framework-connectivity-tiramisu APIs as it is not in the APEX
+ "hiddenapi/hiddenapi-max-target-r-loprio.txt",
],
max_target_o_low_priority: [
"hiddenapi/hiddenapi-max-target-o-low-priority.txt",
- // Changed in sc-mainline-prod only: no list for
- // framework-connectivity-tiramisu APIs as it is not in the APEX
+ "hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt",
],
unsupported: [
"hiddenapi/hiddenapi-unsupported.txt",
- // Changed in sc-mainline-prod only: no framework-connectivity-tiramisu
- // "hiddenapi/hiddenapi-unsupported-tiramisu.txt",
+ "hiddenapi/hiddenapi-unsupported-tiramisu.txt",
],
},
}
diff --git a/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt b/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
index c1d87bb..3a02682 100644
--- a/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
+++ b/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
@@ -1,3 +1,82 @@
+Landroid/app/usage/NetworkStats$Bucket;->convertDefaultNetworkStatus(I)I
+Landroid/app/usage/NetworkStats$Bucket;->convertMetered(I)I
+Landroid/app/usage/NetworkStats$Bucket;->convertRoaming(I)I
+Landroid/app/usage/NetworkStats$Bucket;->convertSet(I)I
+Landroid/app/usage/NetworkStats$Bucket;->convertState(I)I
+Landroid/app/usage/NetworkStats$Bucket;->convertTag(I)I
+Landroid/app/usage/NetworkStats$Bucket;->convertUid(I)I
+Landroid/app/usage/NetworkStats$Bucket;->mBeginTimeStamp:J
+Landroid/app/usage/NetworkStats$Bucket;->mDefaultNetworkStatus:I
+Landroid/app/usage/NetworkStats$Bucket;->mEndTimeStamp:J
+Landroid/app/usage/NetworkStats$Bucket;->mMetered:I
+Landroid/app/usage/NetworkStats$Bucket;->mRoaming:I
+Landroid/app/usage/NetworkStats$Bucket;->mRxBytes:J
+Landroid/app/usage/NetworkStats$Bucket;->mRxPackets:J
+Landroid/app/usage/NetworkStats$Bucket;->mState:I
+Landroid/app/usage/NetworkStats$Bucket;->mTag:I
+Landroid/app/usage/NetworkStats$Bucket;->mTxBytes:J
+Landroid/app/usage/NetworkStats$Bucket;->mTxPackets:J
+Landroid/app/usage/NetworkStats$Bucket;->mUid:I
+Landroid/app/usage/NetworkStats;-><init>(Landroid/content/Context;Landroid/net/NetworkTemplate;IJJLandroid/net/INetworkStatsService;)V
+Landroid/app/usage/NetworkStats;->fillBucketFromSummaryEntry(Landroid/app/usage/NetworkStats$Bucket;)V
+Landroid/app/usage/NetworkStats;->getDeviceSummaryForNetwork()Landroid/app/usage/NetworkStats$Bucket;
+Landroid/app/usage/NetworkStats;->getNextHistoryBucket(Landroid/app/usage/NetworkStats$Bucket;)Z
+Landroid/app/usage/NetworkStats;->getNextSummaryBucket(Landroid/app/usage/NetworkStats$Bucket;)Z
+Landroid/app/usage/NetworkStats;->getSummaryAggregate()Landroid/app/usage/NetworkStats$Bucket;
+Landroid/app/usage/NetworkStats;->getUid()I
+Landroid/app/usage/NetworkStats;->hasNextUid()Z
+Landroid/app/usage/NetworkStats;->isUidEnumeration()Z
+Landroid/app/usage/NetworkStats;->mCloseGuard:Ldalvik/system/CloseGuard;
+Landroid/app/usage/NetworkStats;->mEndTimeStamp:J
+Landroid/app/usage/NetworkStats;->mEnumerationIndex:I
+Landroid/app/usage/NetworkStats;->mHistory:Landroid/net/NetworkStatsHistory;
+Landroid/app/usage/NetworkStats;->mRecycledHistoryEntry:Landroid/net/NetworkStatsHistory$Entry;
+Landroid/app/usage/NetworkStats;->mRecycledSummaryEntry:Landroid/net/NetworkStats$Entry;
+Landroid/app/usage/NetworkStats;->mSession:Landroid/net/INetworkStatsSession;
+Landroid/app/usage/NetworkStats;->mStartTimeStamp:J
+Landroid/app/usage/NetworkStats;->mState:I
+Landroid/app/usage/NetworkStats;->mSummary:Landroid/net/NetworkStats;
+Landroid/app/usage/NetworkStats;->mTag:I
+Landroid/app/usage/NetworkStats;->mTemplate:Landroid/net/NetworkTemplate;
+Landroid/app/usage/NetworkStats;->mUidOrUidIndex:I
+Landroid/app/usage/NetworkStats;->mUids:[I
+Landroid/app/usage/NetworkStats;->setSingleUidTagState(III)V
+Landroid/app/usage/NetworkStats;->startHistoryEnumeration(III)V
+Landroid/app/usage/NetworkStats;->startSummaryEnumeration()V
+Landroid/app/usage/NetworkStats;->startUserUidEnumeration()V
+Landroid/app/usage/NetworkStats;->stepHistory()V
+Landroid/app/usage/NetworkStats;->stepUid()V
+Landroid/app/usage/NetworkStats;->TAG:Ljava/lang/String;
+Landroid/app/usage/NetworkStatsManager$CallbackHandler;-><init>(Landroid/os/Looper;ILjava/lang/String;Landroid/app/usage/NetworkStatsManager$UsageCallback;)V
+Landroid/app/usage/NetworkStatsManager$CallbackHandler;->getObject(Landroid/os/Message;Ljava/lang/String;)Ljava/lang/Object;
+Landroid/app/usage/NetworkStatsManager$CallbackHandler;->mCallback:Landroid/app/usage/NetworkStatsManager$UsageCallback;
+Landroid/app/usage/NetworkStatsManager$CallbackHandler;->mNetworkType:I
+Landroid/app/usage/NetworkStatsManager$CallbackHandler;->mSubscriberId:Ljava/lang/String;
+Landroid/app/usage/NetworkStatsManager$UsageCallback;->request:Landroid/net/DataUsageRequest;
+Landroid/app/usage/NetworkStatsManager;-><init>(Landroid/content/Context;Landroid/net/INetworkStatsService;)V
+Landroid/app/usage/NetworkStatsManager;->CALLBACK_LIMIT_REACHED:I
+Landroid/app/usage/NetworkStatsManager;->CALLBACK_RELEASED:I
+Landroid/app/usage/NetworkStatsManager;->createTemplate(ILjava/lang/String;)Landroid/net/NetworkTemplate;
+Landroid/app/usage/NetworkStatsManager;->DBG:Z
+Landroid/app/usage/NetworkStatsManager;->FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN:I
+Landroid/app/usage/NetworkStatsManager;->FLAG_POLL_FORCE:I
+Landroid/app/usage/NetworkStatsManager;->FLAG_POLL_ON_OPEN:I
+Landroid/app/usage/NetworkStatsManager;->mContext:Landroid/content/Context;
+Landroid/app/usage/NetworkStatsManager;->mFlags:I
+Landroid/app/usage/NetworkStatsManager;->MIN_THRESHOLD_BYTES:J
+Landroid/app/usage/NetworkStatsManager;->mService:Landroid/net/INetworkStatsService;
+Landroid/app/usage/NetworkStatsManager;->querySummaryForDevice(Landroid/net/NetworkTemplate;JJ)Landroid/app/usage/NetworkStats$Bucket;
+Landroid/app/usage/NetworkStatsManager;->registerUsageCallback(Landroid/net/NetworkTemplate;IJLandroid/app/usage/NetworkStatsManager$UsageCallback;Landroid/os/Handler;)V
+Landroid/app/usage/NetworkStatsManager;->setAugmentWithSubscriptionPlan(Z)V
+Landroid/app/usage/NetworkStatsManager;->setPollOnOpen(Z)V
+Landroid/app/usage/NetworkStatsManager;->TAG:Ljava/lang/String;
+Landroid/net/DataUsageRequest;-><init>(ILandroid/net/NetworkTemplate;J)V
+Landroid/net/DataUsageRequest;->CREATOR:Landroid/os/Parcelable$Creator;
+Landroid/net/DataUsageRequest;->PARCELABLE_KEY:Ljava/lang/String;
+Landroid/net/DataUsageRequest;->requestId:I
+Landroid/net/DataUsageRequest;->REQUEST_ID_UNSET:I
+Landroid/net/DataUsageRequest;->template:Landroid/net/NetworkTemplate;
+Landroid/net/DataUsageRequest;->thresholdInBytes:J
Landroid/net/IIpSecService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/IIpSecService$Stub$Proxy;->addAddressToTunnelInterface(ILandroid/net/LinkAddress;Ljava/lang/String;)V
Landroid/net/IIpSecService$Stub$Proxy;->allocateSecurityParameterIndex(Ljava/lang/String;ILandroid/os/IBinder;)Landroid/net/IpSecSpiResponse;
@@ -43,6 +122,68 @@
Landroid/net/IIpSecService;->releaseSecurityParameterIndex(I)V
Landroid/net/IIpSecService;->removeAddressFromTunnelInterface(ILandroid/net/LinkAddress;Ljava/lang/String;)V
Landroid/net/IIpSecService;->removeTransportModeTransforms(Landroid/os/ParcelFileDescriptor;)V
+Landroid/net/INetworkStatsService$Stub$Proxy;->forceUpdate()V
+Landroid/net/INetworkStatsService$Stub$Proxy;->forceUpdateIfaces([Landroid/net/Network;)V
+Landroid/net/INetworkStatsService$Stub$Proxy;->getDataLayerSnapshotForUid(I)Landroid/net/NetworkStats;
+Landroid/net/INetworkStatsService$Stub$Proxy;->getDetailedUidStats([Ljava/lang/String;)Landroid/net/NetworkStats;
+Landroid/net/INetworkStatsService$Stub$Proxy;->getIfaceStats(Ljava/lang/String;I)J
+Landroid/net/INetworkStatsService$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
+Landroid/net/INetworkStatsService$Stub$Proxy;->getTotalStats(I)J
+Landroid/net/INetworkStatsService$Stub$Proxy;->getUidStats(II)J
+Landroid/net/INetworkStatsService$Stub$Proxy;->incrementOperationCount(III)V
+Landroid/net/INetworkStatsService$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/net/INetworkStatsService$Stub$Proxy;->openSession()Landroid/net/INetworkStatsSession;
+Landroid/net/INetworkStatsService$Stub$Proxy;->openSessionForUsageStats(ILjava/lang/String;)Landroid/net/INetworkStatsSession;
+Landroid/net/INetworkStatsService$Stub$Proxy;->registerUsageCallback(Ljava/lang/String;Landroid/net/DataUsageRequest;Landroid/os/Messenger;Landroid/os/IBinder;)Landroid/net/DataUsageRequest;
+Landroid/net/INetworkStatsService$Stub$Proxy;->unregisterUsageRequest(Landroid/net/DataUsageRequest;)V
+Landroid/net/INetworkStatsService$Stub;-><init>()V
+Landroid/net/INetworkStatsService$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_forceUpdate:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_forceUpdateIfaces:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getDataLayerSnapshotForUid:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getDetailedUidStats:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getIfaceStats:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getMobileIfaces:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getTotalStats:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getUidStats:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_incrementOperationCount:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_openSession:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_openSessionForUsageStats:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_registerUsageCallback:I
+Landroid/net/INetworkStatsService$Stub;->TRANSACTION_unregisterUsageRequest:I
+Landroid/net/INetworkStatsService;->forceUpdateIfaces([Landroid/net/Network;)V
+Landroid/net/INetworkStatsService;->getDetailedUidStats([Ljava/lang/String;)Landroid/net/NetworkStats;
+Landroid/net/INetworkStatsService;->getIfaceStats(Ljava/lang/String;I)J
+Landroid/net/INetworkStatsService;->getTotalStats(I)J
+Landroid/net/INetworkStatsService;->getUidStats(II)J
+Landroid/net/INetworkStatsService;->incrementOperationCount(III)V
+Landroid/net/INetworkStatsService;->registerUsageCallback(Ljava/lang/String;Landroid/net/DataUsageRequest;Landroid/os/Messenger;Landroid/os/IBinder;)Landroid/net/DataUsageRequest;
+Landroid/net/INetworkStatsService;->unregisterUsageRequest(Landroid/net/DataUsageRequest;)V
+Landroid/net/INetworkStatsSession$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/net/INetworkStatsSession$Stub$Proxy;->close()V
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getDeviceSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getHistoryForNetwork(Landroid/net/NetworkTemplate;I)Landroid/net/NetworkStatsHistory;
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getHistoryForUid(Landroid/net/NetworkTemplate;IIII)Landroid/net/NetworkStatsHistory;
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getHistoryIntervalForUid(Landroid/net/NetworkTemplate;IIIIJJ)Landroid/net/NetworkStatsHistory;
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getRelevantUids()[I
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getSummaryForAllUid(Landroid/net/NetworkTemplate;JJZ)Landroid/net/NetworkStats;
+Landroid/net/INetworkStatsSession$Stub$Proxy;->getSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
+Landroid/net/INetworkStatsSession$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/net/INetworkStatsSession$Stub;-><init>()V
+Landroid/net/INetworkStatsSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsSession;
+Landroid/net/INetworkStatsSession$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_close:I
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getDeviceSummaryForNetwork:I
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getHistoryForNetwork:I
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getHistoryForUid:I
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getHistoryIntervalForUid:I
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getRelevantUids:I
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getSummaryForAllUid:I
+Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getSummaryForNetwork:I
+Landroid/net/INetworkStatsSession;->getDeviceSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
+Landroid/net/INetworkStatsSession;->getHistoryIntervalForUid(Landroid/net/NetworkTemplate;IIIIJJ)Landroid/net/NetworkStatsHistory;
+Landroid/net/INetworkStatsSession;->getRelevantUids()[I
Landroid/net/IpSecAlgorithm;->checkValidOrThrow(Ljava/lang/String;II)V
Landroid/net/IpSecAlgorithm;->CRYPT_NULL:Ljava/lang/String;
Landroid/net/IpSecAlgorithm;->equals(Landroid/net/IpSecAlgorithm;Landroid/net/IpSecAlgorithm;)Z
@@ -298,3 +439,38 @@
Landroid/net/nsd/NsdServiceInfo;->mTxtRecord:Landroid/util/ArrayMap;
Landroid/net/nsd/NsdServiceInfo;->setTxtRecords(Ljava/lang/String;)V
Landroid/net/nsd/NsdServiceInfo;->TAG:Ljava/lang/String;
+Landroid/net/TrafficStats;->addIfSupported(J)J
+Landroid/net/TrafficStats;->closeQuietly(Landroid/net/INetworkStatsSession;)V
+Landroid/net/TrafficStats;->GB_IN_BYTES:J
+Landroid/net/TrafficStats;->getDataLayerSnapshotForUid(Landroid/content/Context;)Landroid/net/NetworkStats;
+Landroid/net/TrafficStats;->getRxPackets(Ljava/lang/String;)J
+Landroid/net/TrafficStats;->getTxPackets(Ljava/lang/String;)J
+Landroid/net/TrafficStats;->KB_IN_BYTES:J
+Landroid/net/TrafficStats;->LOOPBACK_IFACE:Ljava/lang/String;
+Landroid/net/TrafficStats;->MB_IN_BYTES:J
+Landroid/net/TrafficStats;->PB_IN_BYTES:J
+Landroid/net/TrafficStats;->sActiveProfilingStart:Landroid/net/NetworkStats;
+Landroid/net/TrafficStats;->sProfilingLock:Ljava/lang/Object;
+Landroid/net/TrafficStats;->sStatsService:Landroid/net/INetworkStatsService;
+Landroid/net/TrafficStats;->startDataProfiling(Landroid/content/Context;)V
+Landroid/net/TrafficStats;->stopDataProfiling(Landroid/content/Context;)Landroid/net/NetworkStats;
+Landroid/net/TrafficStats;->TAG_SYSTEM_APP:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_BACKUP:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_DHCP:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_DOWNLOAD:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_GPS:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_MEDIA:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_NEIGHBOR:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_NTP:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_PAC:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_PROBE:I
+Landroid/net/TrafficStats;->TAG_SYSTEM_RESTORE:I
+Landroid/net/TrafficStats;->TB_IN_BYTES:J
+Landroid/net/TrafficStats;->TYPE_RX_BYTES:I
+Landroid/net/TrafficStats;->TYPE_RX_PACKETS:I
+Landroid/net/TrafficStats;->TYPE_TCP_RX_PACKETS:I
+Landroid/net/TrafficStats;->TYPE_TCP_TX_PACKETS:I
+Landroid/net/TrafficStats;->TYPE_TX_BYTES:I
+Landroid/net/TrafficStats;->TYPE_TX_PACKETS:I
+Landroid/net/TrafficStats;->UID_REMOVED:I
+Landroid/net/TrafficStats;->UID_TETHERING:I
diff --git a/Tethering/apex/hiddenapi/hiddenapi-unsupported-tiramisu.txt b/Tethering/apex/hiddenapi/hiddenapi-unsupported-tiramisu.txt
new file mode 100644
index 0000000..a6257e3
--- /dev/null
+++ b/Tethering/apex/hiddenapi/hiddenapi-unsupported-tiramisu.txt
@@ -0,0 +1,3 @@
+Landroid/net/INetworkStatsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
+Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
diff --git a/Tethering/tests/integration/Android.bp b/Tethering/tests/integration/Android.bp
index d2188d1..6eaf68b 100644
--- a/Tethering/tests/integration/Android.bp
+++ b/Tethering/tests/integration/Android.bp
@@ -30,6 +30,7 @@
"androidx.test.rules",
"mockito-target-extended-minus-junit4",
"net-tests-utils",
+ "net-utils-device-common-bpf",
"testables",
],
libs: [
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 8bf1a2b..de81a38 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
+import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.TETHER_PRIVILEGED;
@@ -53,11 +54,15 @@
import android.net.TetheringManager.TetheringEventCallback;
import android.net.TetheringManager.TetheringRequest;
import android.net.TetheringTester.TetheredDevice;
+import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Base64;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -67,17 +72,24 @@
import com.android.net.module.util.PacketBuilder;
import com.android.net.module.util.Struct;
+import com.android.net.module.util.bpf.Tether4Key;
+import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.structs.EthernetHeader;
import com.android.net.module.util.structs.Icmpv6Header;
import com.android.net.module.util.structs.Ipv4Header;
import com.android.net.module.util.structs.Ipv6Header;
import com.android.net.module.util.structs.UdpHeader;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DumpTestUtils;
import com.android.testutils.HandlerUtils;
import com.android.testutils.TapPacketReader;
import com.android.testutils.TestNetworkTracker;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -88,9 +100,13 @@
import java.net.NetworkInterface;
import java.net.SocketException;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -101,10 +117,17 @@
@RunWith(AndroidJUnit4.class)
@MediumTest
public class EthernetTetheringTest {
+ @Rule
+ public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
private static final String TAG = EthernetTetheringTest.class.getSimpleName();
private static final int TIMEOUT_MS = 5000;
private static final int TETHER_REACHABILITY_ATTEMPTS = 20;
+ private static final int DUMP_POLLING_MAX_RETRY = 100;
+ private static final int DUMP_POLLING_INTERVAL_MS = 50;
+ // Kernel treats a confirmed UDP connection which active after two seconds as stream mode.
+ // See upstream commit b7b1d02fc43925a4d569ec221715db2dfa1ce4f5.
+ private static final int UDP_STREAM_TS_MS = 2000;
private static final LinkAddress TEST_IP4_ADDR = new LinkAddress("10.0.0.1/8");
private static final LinkAddress TEST_IP6_ADDR = new LinkAddress("2001:db8:1::101/64");
private static final InetAddress TEST_IP4_DNS = parseNumericAddress("8.8.8.8");
@@ -112,6 +135,10 @@
private static final ByteBuffer TEST_REACHABILITY_PAYLOAD =
ByteBuffer.wrap(new byte[] { (byte) 0x55, (byte) 0xaa });
+ private static final String DUMPSYS_TETHERING_RAWMAP_ARG = "bpfRawMap";
+ private static final String BASE64_DELIMITER = ",";
+ private static final String LINE_DELIMITER = "\\n";
+
private final Context mContext = InstrumentationRegistry.getContext();
private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
private final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
@@ -136,10 +163,11 @@
// Needed to create a TestNetworkInterface, to call requestTetheredInterface, and to receive
// tethered client callbacks. The restricted networks permission is needed to ensure that
// EthernetManager#isAvailable will correctly return true on devices where Ethernet is
- // marked restricted, like cuttlefish.
+ // marked restricted, like cuttlefish. The dump permission is needed to verify bpf related
+ // functions via dumpsys output.
mUiAutomation.adoptShellPermissionIdentity(
MANAGE_TEST_NETWORKS, NETWORK_SETTINGS, TETHER_PRIVILEGED, ACCESS_NETWORK_STATE,
- CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+ CONNECTIVITY_USE_RESTRICTED_NETWORKS, DUMP);
mRunTests = mTm.isTetheringSupported() && mEm != null;
assumeTrue(mRunTests);
@@ -251,7 +279,7 @@
final String localAddr = "192.0.2.3/28";
final String clientAddr = "192.0.2.2/28";
mTetheringEventCallback = enableEthernetTethering(iface,
- requestWithStaticIpv4(localAddr, clientAddr));
+ requestWithStaticIpv4(localAddr, clientAddr), null /* any upstream */);
mTetheringEventCallback.awaitInterfaceTethered();
assertInterfaceHasIpAddress(iface, localAddr);
@@ -334,7 +362,8 @@
final TetheringRequest request = new TetheringRequest.Builder(TETHERING_ETHERNET)
.setConnectivityScope(CONNECTIVITY_SCOPE_LOCAL).build();
- mTetheringEventCallback = enableEthernetTethering(iface, request);
+ mTetheringEventCallback = enableEthernetTethering(iface, request,
+ null /* any upstream */);
mTetheringEventCallback.awaitInterfaceLocalOnly();
// makePacketReader only works after tethering is started, because until then the interface
@@ -365,7 +394,7 @@
final String iface = mTetheredInterfaceRequester.getInterface();
// Enable Ethernet tethering and check that it starts.
- mTetheringEventCallback = enableEthernetTethering(iface);
+ mTetheringEventCallback = enableEthernetTethering(iface, null /* any upstream */);
// There is nothing more we can do on a physical interface without connecting an actual
// client, which is not possible in this test.
@@ -378,8 +407,11 @@
private final CountDownLatch mLocalOnlyStartedLatch = new CountDownLatch(1);
private final CountDownLatch mLocalOnlyStoppedLatch = new CountDownLatch(1);
private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
- private final CountDownLatch mUpstreamConnectedLatch = new CountDownLatch(1);
+ private final CountDownLatch mUpstreamLatch = new CountDownLatch(1);
private final TetheringInterface mIface;
+ private final Network mExpectedUpstream;
+
+ private boolean mAcceptAnyUpstream = false;
private volatile boolean mInterfaceWasTethered = false;
private volatile boolean mInterfaceWasLocalOnly = false;
@@ -388,8 +420,14 @@
private volatile Network mUpstream = null;
MyTetheringEventCallback(TetheringManager tm, String iface) {
+ this(tm, iface, null);
+ mAcceptAnyUpstream = true;
+ }
+
+ MyTetheringEventCallback(TetheringManager tm, String iface, Network expectedUpstream) {
mTm = tm;
mIface = new TetheringInterface(TETHERING_ETHERNET, iface);
+ mExpectedUpstream = expectedUpstream;
}
public void unregister() {
@@ -499,19 +537,30 @@
Log.d(TAG, "Got upstream changed: " + network);
mUpstream = network;
- if (mUpstream != null) mUpstreamConnectedLatch.countDown();
+ if (mAcceptAnyUpstream || Objects.equals(mUpstream, mExpectedUpstream)) {
+ mUpstreamLatch.countDown();
+ }
}
- public Network awaitFirstUpstreamConnected() throws Exception {
- assertTrue("Did not receive upstream connected callback after " + TIMEOUT_MS + "ms",
- mUpstreamConnectedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ public Network awaitUpstreamChanged() throws Exception {
+ if (!mUpstreamLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("Did not receive upstream " + (mAcceptAnyUpstream ? "any" : mExpectedUpstream)
+ + " callback after " + TIMEOUT_MS + "ms");
+ }
return mUpstream;
}
}
private MyTetheringEventCallback enableEthernetTethering(String iface,
- TetheringRequest request) throws Exception {
- MyTetheringEventCallback callback = new MyTetheringEventCallback(mTm, iface);
+ TetheringRequest request, Network expectedUpstream) throws Exception {
+ // Enable ethernet tethering with null expectedUpstream means the test accept any upstream
+ // after etherent tethering started.
+ final MyTetheringEventCallback callback;
+ if (expectedUpstream != null) {
+ callback = new MyTetheringEventCallback(mTm, iface, expectedUpstream);
+ } else {
+ callback = new MyTetheringEventCallback(mTm, iface);
+ }
mTm.registerTetheringEventCallback(mHandler::post, callback);
StartTetheringCallback startTetheringCallback = new StartTetheringCallback() {
@@ -538,10 +587,11 @@
return callback;
}
- private MyTetheringEventCallback enableEthernetTethering(String iface) throws Exception {
+ private MyTetheringEventCallback enableEthernetTethering(String iface, Network expectedUpstream)
+ throws Exception {
return enableEthernetTethering(iface,
new TetheringRequest.Builder(TETHERING_ETHERNET)
- .setShouldShowEntitlementUi(false).build());
+ .setShouldShowEntitlementUi(false).build(), expectedUpstream);
}
private int getMTU(TestNetworkInterface iface) throws SocketException {
@@ -565,7 +615,8 @@
private void checkVirtualEthernet(TestNetworkInterface iface, int mtu) throws Exception {
FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
mDownstreamReader = makePacketReader(fd, mtu);
- mTetheringEventCallback = enableEthernetTethering(iface.getInterfaceName());
+ mTetheringEventCallback = enableEthernetTethering(iface.getInterfaceName(),
+ null /* any upstream */);
checkTetheredClientCallbacks(mDownstreamReader);
}
@@ -663,7 +714,8 @@
private void assertInvalidStaticIpv4Request(String iface, String local, String client)
throws Exception {
try {
- enableEthernetTethering(iface, requestWithStaticIpv4(local, client));
+ enableEthernetTethering(iface, requestWithStaticIpv4(local, client),
+ null /* any upstream */);
fail("Unexpectedly accepted invalid IPv4 configuration: " + local + ", " + client);
} catch (IllegalArgumentException | NullPointerException expected) { }
}
@@ -719,9 +771,10 @@
assertEquals("TetheredInterfaceCallback for unexpected interface",
mDownstreamIface.getInterfaceName(), iface);
- mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName());
+ mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName(),
+ mUpstreamTracker.getNetwork());
assertEquals("onUpstreamChanged for unexpected network", mUpstreamTracker.getNetwork(),
- mTetheringEventCallback.awaitFirstUpstreamConnected());
+ mTetheringEventCallback.awaitUpstreamChanged());
mDownstreamReader = makePacketReader(mDownstreamIface);
// TODO: do basic forwarding test here.
@@ -747,12 +800,15 @@
private static final byte TYPE_OF_SERVICE = 0;
private static final short ID = 27149;
private static final short ID2 = 27150;
+ private static final short ID3 = 27151;
private static final short FLAGS_AND_FRAGMENT_OFFSET = (short) 0x4000; // flags=DF, offset=0
private static final byte TIME_TO_LIVE = (byte) 0x40;
private static final ByteBuffer PAYLOAD =
ByteBuffer.wrap(new byte[] { (byte) 0x12, (byte) 0x34 });
private static final ByteBuffer PAYLOAD2 =
ByteBuffer.wrap(new byte[] { (byte) 0x56, (byte) 0x78 });
+ private static final ByteBuffer PAYLOAD3 =
+ ByteBuffer.wrap(new byte[] { (byte) 0x9a, (byte) 0xbc });
private boolean isExpectedUdpPacket(@NonNull final byte[] rawPacket, boolean hasEther,
@NonNull final ByteBuffer payload) {
@@ -830,7 +886,8 @@
return false;
}
- private void runUdp4Test(TetheringTester tester, RemoteResponder remote) throws Exception {
+ private void runUdp4Test(TetheringTester tester, RemoteResponder remote, boolean usingBpf)
+ throws Exception {
final TetheredDevice tethered = tester.createTetheredDevice(MacAddress.fromString(
"1:2:3:4:5:6"));
@@ -861,10 +918,51 @@
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
return isExpectedUdpPacket(p, true/* hasEther */, PAYLOAD2);
});
+
+ if (usingBpf) {
+ // Send second UDP packet in original direction.
+ // The BPF coordinator only offloads the ASSURED conntrack entry. The "request + reply"
+ // packets can make status IPS_SEEN_REPLY to be set. Need one more packet to make
+ // conntrack status IPS_ASSURED_BIT to be set. Note the third packet needs to delay
+ // 2 seconds because kernel monitors a UDP connection which still alive after 2 seconds
+ // and apply ASSURED flag.
+ // See kernel upstream commit b7b1d02fc43925a4d569ec221715db2dfa1ce4f5 and
+ // nf_conntrack_udp_packet in net/netfilter/nf_conntrack_proto_udp.c
+ Thread.sleep(UDP_STREAM_TS_MS);
+ final ByteBuffer originalPacket2 = buildUdpv4Packet(tethered.macAddr,
+ tethered.routerMacAddr, ID, tethered.ipv4Addr /* srcIp */,
+ REMOTE_IP4_ADDR /* dstIp */, LOCAL_PORT /* srcPort */,
+ REMOTE_PORT /*dstPort */, PAYLOAD3 /* payload */);
+ tester.verifyUpload(remote, originalPacket2, p -> {
+ Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+ return isExpectedUdpPacket(p, false /* hasEther */, PAYLOAD3);
+ });
+
+ final HashMap<Tether4Key, Tether4Value> upstreamMap = pollIpv4UpstreamMapFromDump();
+ assertNotNull(upstreamMap);
+ assertEquals(1, upstreamMap.size());
+
+ final Map.Entry<Tether4Key, Tether4Value> rule =
+ upstreamMap.entrySet().iterator().next();
+
+ final Tether4Key key = rule.getKey();
+ assertEquals(IPPROTO_UDP, key.l4proto);
+ assertTrue(Arrays.equals(tethered.ipv4Addr.getAddress(), key.src4));
+ assertEquals(LOCAL_PORT, key.srcPort);
+ assertTrue(Arrays.equals(REMOTE_IP4_ADDR.getAddress(), key.dst4));
+ assertEquals(REMOTE_PORT, key.dstPort);
+
+ final Tether4Value value = rule.getValue();
+ assertTrue(Arrays.equals(publicIp4Addr.getAddress(),
+ InetAddress.getByAddress(value.src46).getAddress()));
+ assertEquals(LOCAL_PORT, value.srcPort);
+ assertTrue(Arrays.equals(REMOTE_IP4_ADDR.getAddress(),
+ InetAddress.getByAddress(value.dst46).getAddress()));
+ assertEquals(REMOTE_PORT, value.dstPort);
+ }
}
- @Test
- public void testUdpV4() throws Exception {
+ void initializeTethering() throws Exception {
assumeFalse(mEm.isAvailable());
// MyTetheringEventCallback currently only support await first available upstream. Tethering
@@ -879,14 +977,82 @@
assertEquals("TetheredInterfaceCallback for unexpected interface",
mDownstreamIface.getInterfaceName(), iface);
- mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName());
+ mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName(),
+ mUpstreamTracker.getNetwork());
assertEquals("onUpstreamChanged for unexpected network", mUpstreamTracker.getNetwork(),
- mTetheringEventCallback.awaitFirstUpstreamConnected());
+ mTetheringEventCallback.awaitUpstreamChanged());
mDownstreamReader = makePacketReader(mDownstreamIface);
mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
+ }
- runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader));
+ @Test
+ @IgnoreAfter(Build.VERSION_CODES.Q)
+ public void testTetherUdpV4WithoutBpf() throws Exception {
+ initializeTethering();
+ runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader),
+ false /* usingBpf */);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testTetherUdpV4WithBpf() throws Exception {
+ initializeTethering();
+ runUdp4Test(new TetheringTester(mDownstreamReader), new RemoteResponder(mUpstreamReader),
+ true /* usingBpf */);
+ }
+
+ @Nullable
+ private Pair<Tether4Key, Tether4Value> parseTether4KeyValue(@NonNull String dumpStr) {
+ Log.w(TAG, "Parsing string: " + dumpStr);
+
+ String[] keyValueStrs = dumpStr.split(BASE64_DELIMITER);
+ if (keyValueStrs.length != 2 /* key + value */) {
+ fail("The length is " + keyValueStrs.length + " but expect 2. "
+ + "Split string(s): " + TextUtils.join(",", keyValueStrs));
+ }
+
+ final byte[] keyBytes = Base64.decode(keyValueStrs[0], Base64.DEFAULT);
+ Log.d(TAG, "keyBytes: " + dumpHexString(keyBytes));
+ final ByteBuffer keyByteBuffer = ByteBuffer.wrap(keyBytes);
+ keyByteBuffer.order(ByteOrder.nativeOrder());
+ final Tether4Key tether4Key = Struct.parse(Tether4Key.class, keyByteBuffer);
+ Log.w(TAG, "tether4Key: " + tether4Key);
+
+ final byte[] valueBytes = Base64.decode(keyValueStrs[1], Base64.DEFAULT);
+ Log.d(TAG, "valueBytes: " + dumpHexString(valueBytes));
+ final ByteBuffer valueByteBuffer = ByteBuffer.wrap(valueBytes);
+ valueByteBuffer.order(ByteOrder.nativeOrder());
+ final Tether4Value tether4Value = Struct.parse(Tether4Value.class, valueByteBuffer);
+ Log.w(TAG, "tether4Value: " + tether4Value);
+
+ return new Pair<>(tether4Key, tether4Value);
+ }
+
+ @NonNull
+ private HashMap<Tether4Key, Tether4Value> dumpIpv4UpstreamMap() throws Exception {
+ final String rawMapStr = DumpTestUtils.dumpService(Context.TETHERING_SERVICE,
+ DUMPSYS_TETHERING_RAWMAP_ARG);
+ final HashMap<Tether4Key, Tether4Value> map = new HashMap<>();
+
+ for (final String line : rawMapStr.split(LINE_DELIMITER)) {
+ final Pair<Tether4Key, Tether4Value> rule = parseTether4KeyValue(line.trim());
+ map.put(rule.first, rule.second);
+ }
+ return map;
+ }
+
+ @Nullable
+ private HashMap<Tether4Key, Tether4Value> pollIpv4UpstreamMapFromDump() throws Exception {
+ for (int retryCount = 0; retryCount < DUMP_POLLING_MAX_RETRY; retryCount++) {
+ final HashMap<Tether4Key, Tether4Value> map = dumpIpv4UpstreamMap();
+ if (!map.isEmpty()) return map;
+
+ Thread.sleep(DUMP_POLLING_INTERVAL_MS);
+ }
+
+ fail("Cannot get rules after " + DUMP_POLLING_MAX_RETRY * DUMP_POLLING_INTERVAL_MS + "ms");
+ return null;
}
private <T> List<T> toList(T... array) {
diff --git a/Tethering/tests/privileged/src/com/android/net/module/util/BpfBitmapTest.java b/Tethering/tests/privileged/src/com/android/net/module/util/BpfBitmapTest.java
new file mode 100644
index 0000000..2112396
--- /dev/null
+++ b/Tethering/tests/privileged/src/com/android/net/module/util/BpfBitmapTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.networkstack.tethering;
+
+import static com.android.networkstack.tethering.util.TetheringUtils.getTetheringJniLibraryName;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.net.module.util.BpfBitmap;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(DevSdkIgnoreRunner.class)
+public final class BpfBitmapTest {
+ private static final String TEST_BITMAP_PATH =
+ "/sys/fs/bpf/tethering/map_test_bitmap";
+
+ private static final int mTestData[] = {0,1,2,6,63,64,72};
+ private BpfBitmap mTestBitmap;
+
+ @Before
+ public void setUp() throws Exception {
+ mTestBitmap = new BpfBitmap(TEST_BITMAP_PATH);
+ mTestBitmap.clear();
+ assertTrue(mTestBitmap.isEmpty());
+ }
+
+ @Test
+ public void testSet() throws Exception {
+ for (int i : mTestData) {
+ mTestBitmap.set(i);
+ assertFalse(mTestBitmap.isEmpty());
+ assertTrue(mTestBitmap.get(i));
+ // Check that the next item in the bitmap is unset since test data is in
+ // ascending order.
+ assertFalse(mTestBitmap.get(i + 1));
+ }
+ }
+
+ @Test
+ public void testSetThenUnset() throws Exception {
+ for (int i : mTestData) {
+ mTestBitmap.set(i);
+ assertFalse(mTestBitmap.isEmpty());
+ assertTrue(mTestBitmap.get(i));
+ // Since test unsets all test data during each iteration, ensure all other
+ // bit are unset.
+ for (int j = 0; j < 128; ++j) if (j != i) assertFalse(mTestBitmap.get(j));
+ mTestBitmap.unset(i);
+ }
+ }
+
+ @Test
+ public void testSetAllThenUnsetAll() throws Exception {
+ for (int i : mTestData) {
+ mTestBitmap.set(i);
+ }
+
+ for (int i : mTestData) {
+ mTestBitmap.unset(i);
+ if (i < mTestData.length)
+ assertFalse(mTestBitmap.isEmpty());
+ assertFalse(mTestBitmap.get(i));
+ }
+ assertTrue(mTestBitmap.isEmpty());
+ }
+
+ @Test
+ public void testClear() throws Exception {
+ for (int i = 0; i < 128; ++i) {
+ mTestBitmap.set(i);
+ }
+ assertFalse(mTestBitmap.isEmpty());
+ mTestBitmap.clear();
+ assertTrue(mTestBitmap.isEmpty());
+ }
+}
diff --git a/Tethering/tests/unit/Android.bp b/Tethering/tests/unit/Android.bp
index ecd1a39..37b1bc8 100644
--- a/Tethering/tests/unit/Android.bp
+++ b/Tethering/tests/unit/Android.bp
@@ -34,6 +34,7 @@
libs: [
"framework-minus-apex",
"framework-connectivity.impl",
+ "framework-connectivity-t.impl",
"framework-tethering.impl",
],
visibility: [
@@ -66,7 +67,9 @@
"ext",
"framework-minus-apex",
"framework-res",
+ "framework-bluetooth.stubs.module_lib",
"framework-connectivity.impl",
+ "framework-connectivity-t.impl",
"framework-tethering.impl",
"framework-wifi.stubs.module_lib",
],
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index 8d05757..fe9a871 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -340,9 +340,11 @@
DEFINE_BPF_PROG("schedact/ingress/account", AID_ROOT, AID_NET_ADMIN, tc_bpf_ingress_account_prog)
(struct __sk_buff* skb) {
- // Account for ingress traffic before tc drops it.
- uint32_t key = skb->ifindex;
- update_iface_stats_map(skb, BPF_INGRESS, &key);
+ if (is_received_skb(skb)) {
+ // Account for ingress traffic before tc drops it.
+ uint32_t key = skb->ifindex;
+ update_iface_stats_map(skb, BPF_INGRESS, &key);
+ }
return TC_ACT_UNSPEC;
}
diff --git a/bpf_progs/test.c b/bpf_progs/test.c
index a76e346..c9c73f1 100644
--- a/bpf_progs/test.c
+++ b/bpf_progs/test.c
@@ -28,6 +28,9 @@
// Used only by TetheringPrivilegedTests, not by production code.
DEFINE_BPF_MAP_GRW(tether_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 16,
AID_NETWORK_STACK)
+// Used only by BpfBitmapTest, not by production code.
+DEFINE_BPF_MAP_GRW(bitmap, ARRAY, int, uint64_t, 2,
+ AID_NETWORK_STACK)
DEFINE_BPF_PROG_KVER("xdp/drop_ipv4_udp_ether", AID_ROOT, AID_NETWORK_STACK,
xdp_test, KVER(5, 9, 0))
diff --git a/buildstubs-t/Android.bp b/buildstubs-t/Android.bp
deleted file mode 100644
index 396827f..0000000
--- a/buildstubs-t/Android.bp
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- // See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-// Placeholder empty filegroups to avoid merge conflicts on build rules
-// on a branch that does not have the filegroups
-
-filegroup {
- name: "framework-connectivity-tiramisu-updatable-sources",
- srcs: [],
-}
-
-filegroup {
- name: "services.connectivity-tiramisu-updatable-sources",
- srcs: ["stubs-src/**/*.java"],
-}
-
-filegroup {
- name: "framework-connectivity-api-shared-srcs",
- srcs: [],
-}
-
-filegroup {
- name: "services.connectivity-netstats-jni-sources",
- srcs: [
- "stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp",
- "stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp",
- ],
- visibility: [
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-filegroup {
- name: "framework-connectivity-tiramisu-jni-sources",
- srcs: [
- "stubs-src-jni/mock_android_net_TrafficStats.cpp",
- ],
- visibility: [
- "//packages/modules/Connectivity:__subpackages__",
- ],
-}
-
-// Empty replacement for framework-connectivity-tiramisu.impl and stubs,
-// as framework-connectivity is disabled in the branch
-java_library {
- name: "framework-connectivity-tiramisu.impl",
- min_sdk_version: "Tiramisu",
- sdk_version: "module_current",
- srcs: [],
-}
-
-java_library {
- name: "framework-connectivity-tiramisu.stubs.module_lib",
- min_sdk_version: "Tiramisu",
- sdk_version: "module_current",
- srcs: [],
-}
diff --git a/buildstubs-t/stubs-src-jni/mock_android_net_TrafficStats.cpp b/buildstubs-t/stubs-src-jni/mock_android_net_TrafficStats.cpp
deleted file mode 100644
index ef5d874..0000000
--- a/buildstubs-t/stubs-src-jni/mock_android_net_TrafficStats.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-int register_android_net_TrafficStats(JNIEnv* env) {
- return JNI_ERR;
-}
-
-}; // namespace android
diff --git a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp b/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp
deleted file mode 100644
index 594a174..0000000
--- a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsFactory.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-int register_android_server_net_NetworkStatsFactory(JNIEnv* env) {
- return JNI_ERR;
-}
-
-}; // namespace android
diff --git a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp b/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp
deleted file mode 100644
index b0c42b0..0000000
--- a/buildstubs-t/stubs-src-jni/mock_com_android_server_net_NetworkStatsService.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <nativehelper/JNIHelp.h>
-
-namespace android {
-
-int register_android_server_net_NetworkStatsService(JNIEnv* env) {
- return JNI_ERR;
-}
-
-}; // namespace android
diff --git a/buildstubs-t/stubs-src/android/net/TrafficStats.java b/buildstubs-t/stubs-src/android/net/TrafficStats.java
deleted file mode 100644
index 0b208ac..0000000
--- a/buildstubs-t/stubs-src/android/net/TrafficStats.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.Context;
-
-/**
- * Fake TrafficStats class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch.
- */
-public final class TrafficStats {
- /** Init */
- public static void init(Context context) {
- throw new RuntimeException("This is a stub class");
- }
-}
diff --git a/buildstubs-t/stubs-src/com/android/server/IpSecService.java b/buildstubs-t/stubs-src/com/android/server/IpSecService.java
deleted file mode 100644
index bb48c14..0000000
--- a/buildstubs-t/stubs-src/com/android/server/IpSecService.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.content.Context;
-import android.os.Binder;
-
-/**
- * Fake IpSecManager class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch
- */
-public final class IpSecService extends Binder {
- public IpSecService(Context ctx) {
- throw new RuntimeException("This is a stub class");
- }
-}
diff --git a/buildstubs-t/stubs-src/com/android/server/NsdService.java b/buildstubs-t/stubs-src/com/android/server/NsdService.java
deleted file mode 100644
index 4a3ba90..0000000
--- a/buildstubs-t/stubs-src/com/android/server/NsdService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.content.Context;
-import android.os.Binder;
-
-/**
- * Fake NsdService class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch
- */
-public final class NsdService extends Binder {
- /** Create instance */
- public static NsdService create(Context ctx) throws InterruptedException {
- throw new RuntimeException("This is a stub class");
- }
-}
diff --git a/buildstubs-t/stubs-src/com/android/server/net/NetworkStatsService.java b/buildstubs-t/stubs-src/com/android/server/net/NetworkStatsService.java
deleted file mode 100644
index 8568e2a..0000000
--- a/buildstubs-t/stubs-src/com/android/server/net/NetworkStatsService.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.net;
-
-import android.content.Context;
-import android.os.Binder;
-
-/**
- * Fake NetworkStatsService class for sc-mainline-prod,
- * to allow building the T service-connectivity before sources
- * are moved to the branch
- */
-public final class NetworkStatsService extends Binder {
- /** Create instance */
- public static NetworkStatsService create(Context ctx) {
- throw new RuntimeException("This is a stub class");
- }
-
- /** System Ready */
- public void systemReady() {
- throw new RuntimeException("This is a stub class");
- }
-}
diff --git a/framework-t/Android.bp b/framework-t/Android.bp
index 3c36f87..2ab69b8 100644
--- a/framework-t/Android.bp
+++ b/framework-t/Android.bp
@@ -21,7 +21,7 @@
java_defaults {
name: "enable-framework-connectivity-t-targets",
- enabled: false,
+ enabled: true,
}
// The above defaults can be used to disable framework-connectivity t
// targets while minimizing merge conflicts in the build rules.
@@ -30,7 +30,7 @@
// T, and were moved to the module in T. Other bootclasspath classes in connectivity should go to
// framework-connectivity.
java_defaults {
- name: "framework-connectivity-tiramisu-defaults",
+ name: "framework-connectivity-t-defaults",
sdk_version: "module_current",
min_sdk_version: "Tiramisu",
defaults: [
@@ -53,6 +53,7 @@
// The build system will use framework-bluetooth module_current stubs, because
// of sdk_version: "module_current" above.
"framework-bluetooth",
+ "framework-wifi",
// Compile against the entire implementation of framework-connectivity,
// including hidden methods. This is safe because if framework-connectivity-t is
// on the bootclasspath (i.e., T), then framework-connectivity is also on the
@@ -77,10 +78,11 @@
}
java_library {
- name: "framework-connectivity-tiramisu-pre-jarjar",
- defaults: ["framework-connectivity-tiramisu-defaults"],
+ name: "framework-connectivity-t-pre-jarjar",
+ defaults: ["framework-connectivity-t-defaults"],
libs: [
"framework-bluetooth",
+ "framework-wifi",
"framework-connectivity-pre-jarjar",
],
visibility: ["//packages/modules/Connectivity:__subpackages__"],
@@ -90,9 +92,9 @@
// T, and were moved to the module in T. Other bootclasspath classes in connectivity should go to
// framework-connectivity.
java_sdk_library {
- name: "framework-connectivity-tiramisu",
+ name: "framework-connectivity-t",
defaults: [
- "framework-connectivity-tiramisu-defaults",
+ "framework-connectivity-t-defaults",
"enable-framework-connectivity-t-targets",
],
// Do not add static_libs to this library: put them in framework-connectivity instead.
@@ -100,6 +102,7 @@
// framework-connectivity-pre-jarjar match at runtime.
jarjar_rules: ":connectivity-jarjar-rules",
permitted_packages: [
+ "android.app.usage",
"android.net",
"android.net.nsd",
"android.nearby",
diff --git a/framework-t/api/current.txt b/framework-t/api/current.txt
index 1389ff2..3d6fb3e 100644
--- a/framework-t/api/current.txt
+++ b/framework-t/api/current.txt
@@ -1,4 +1,64 @@
// Signature format: 2.0
+package android.app.usage {
+
+ public final class NetworkStats implements java.lang.AutoCloseable {
+ method public void close();
+ method public boolean getNextBucket(android.app.usage.NetworkStats.Bucket);
+ method public boolean hasNextBucket();
+ }
+
+ public static class NetworkStats.Bucket {
+ ctor public NetworkStats.Bucket();
+ method public int getDefaultNetworkStatus();
+ method public long getEndTimeStamp();
+ method public int getMetered();
+ method public int getRoaming();
+ method public long getRxBytes();
+ method public long getRxPackets();
+ method public long getStartTimeStamp();
+ method public int getState();
+ method public int getTag();
+ method public long getTxBytes();
+ method public long getTxPackets();
+ method public int getUid();
+ field public static final int DEFAULT_NETWORK_ALL = -1; // 0xffffffff
+ field public static final int DEFAULT_NETWORK_NO = 1; // 0x1
+ field public static final int DEFAULT_NETWORK_YES = 2; // 0x2
+ field public static final int METERED_ALL = -1; // 0xffffffff
+ field public static final int METERED_NO = 1; // 0x1
+ field public static final int METERED_YES = 2; // 0x2
+ field public static final int ROAMING_ALL = -1; // 0xffffffff
+ field public static final int ROAMING_NO = 1; // 0x1
+ field public static final int ROAMING_YES = 2; // 0x2
+ field public static final int STATE_ALL = -1; // 0xffffffff
+ field public static final int STATE_DEFAULT = 1; // 0x1
+ field public static final int STATE_FOREGROUND = 2; // 0x2
+ field public static final int TAG_NONE = 0; // 0x0
+ field public static final int UID_ALL = -1; // 0xffffffff
+ field public static final int UID_REMOVED = -4; // 0xfffffffc
+ field public static final int UID_TETHERING = -5; // 0xfffffffb
+ }
+
+ public class NetworkStatsManager {
+ method @WorkerThread public android.app.usage.NetworkStats queryDetails(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUid(int, String, long, long, int) throws java.lang.SecurityException;
+ method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTag(int, String, long, long, int, int) throws java.lang.SecurityException;
+ method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(int, String, long, long, int, int, int) throws java.lang.SecurityException;
+ method @WorkerThread public android.app.usage.NetworkStats querySummary(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method public void registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback);
+ method public void registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, @Nullable android.os.Handler);
+ method public void unregisterUsageCallback(android.app.usage.NetworkStatsManager.UsageCallback);
+ }
+
+ public abstract static class NetworkStatsManager.UsageCallback {
+ ctor public NetworkStatsManager.UsageCallback();
+ method public abstract void onThresholdReached(int, String);
+ }
+
+}
+
package android.net {
public final class IpSecAlgorithm implements android.os.Parcelable {
@@ -70,6 +130,50 @@
method @NonNull public android.net.IpSecTransform.Builder setIpv4Encapsulation(@NonNull android.net.IpSecManager.UdpEncapsulationSocket, int);
}
+ public class TrafficStats {
+ ctor public TrafficStats();
+ method public static void clearThreadStatsTag();
+ method public static void clearThreadStatsUid();
+ method public static int getAndSetThreadStatsTag(int);
+ method public static long getMobileRxBytes();
+ method public static long getMobileRxPackets();
+ method public static long getMobileTxBytes();
+ method public static long getMobileTxPackets();
+ method public static long getRxBytes(@NonNull String);
+ method public static long getRxPackets(@NonNull String);
+ method public static int getThreadStatsTag();
+ method public static int getThreadStatsUid();
+ method public static long getTotalRxBytes();
+ method public static long getTotalRxPackets();
+ method public static long getTotalTxBytes();
+ method public static long getTotalTxPackets();
+ method public static long getTxBytes(@NonNull String);
+ method public static long getTxPackets(@NonNull String);
+ method public static long getUidRxBytes(int);
+ method public static long getUidRxPackets(int);
+ method @Deprecated public static long getUidTcpRxBytes(int);
+ method @Deprecated public static long getUidTcpRxSegments(int);
+ method @Deprecated public static long getUidTcpTxBytes(int);
+ method @Deprecated public static long getUidTcpTxSegments(int);
+ method public static long getUidTxBytes(int);
+ method public static long getUidTxPackets(int);
+ method @Deprecated public static long getUidUdpRxBytes(int);
+ method @Deprecated public static long getUidUdpRxPackets(int);
+ method @Deprecated public static long getUidUdpTxBytes(int);
+ method @Deprecated public static long getUidUdpTxPackets(int);
+ method public static void incrementOperationCount(int);
+ method public static void incrementOperationCount(int, int);
+ method public static void setThreadStatsTag(int);
+ method public static void setThreadStatsUid(int);
+ method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+ method public static void tagFileDescriptor(java.io.FileDescriptor) throws java.io.IOException;
+ method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
+ method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+ method public static void untagFileDescriptor(java.io.FileDescriptor) throws java.io.IOException;
+ method public static void untagSocket(java.net.Socket) throws java.net.SocketException;
+ field public static final int UNSUPPORTED = -1; // 0xffffffff
+ }
+
}
package android.net.nsd {
diff --git a/framework-t/api/lint-baseline.txt b/framework-t/api/lint-baseline.txt
index 1e30747..53e1beb 100644
--- a/framework-t/api/lint-baseline.txt
+++ b/framework-t/api/lint-baseline.txt
@@ -1,7 +1,157 @@
// Baseline format: 1.0
+BannedThrow: android.app.usage.NetworkStatsManager#queryDetails(int, String, long, long):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#queryDetailsForUid(int, String, long, long, int):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#queryDetailsForUidTag(int, String, long, long, int, int):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#queryDetailsForUidTagState(int, String, long, long, int, int, int):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#querySummary(int, String, long, long):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#querySummaryForDevice(int, String, long, long):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#querySummaryForUser(int, String, long, long):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+
+
+BuilderSetStyle: android.net.IpSecTransform.Builder#buildTransportModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTransportModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex)
+
+
+EqualsAndHashCode: android.net.IpSecTransform#equals(Object):
+ Must override both equals and hashCode; missing one in android.net.IpSecTransform
+
+
+ExecutorRegistration: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler):
+ Registration methods should have overload that accepts delivery Executor: `registerUsageCallback`
+
+
+GenericException: android.app.usage.NetworkStats#finalize():
+ Methods must not throw generic exceptions (`java.lang.Throwable`)
GenericException: android.net.IpSecManager.SecurityParameterIndex#finalize():
Methods must not throw generic exceptions (`java.lang.Throwable`)
GenericException: android.net.IpSecManager.UdpEncapsulationSocket#finalize():
Methods must not throw generic exceptions (`java.lang.Throwable`)
GenericException: android.net.IpSecTransform#finalize():
Methods must not throw generic exceptions (`java.lang.Throwable`)
+
+
+MissingBuildMethod: android.net.IpSecTransform.Builder:
+ android.net.IpSecTransform.Builder does not declare a `build()` method, but builder classes are expected to
+
+
+MissingNullability: android.app.usage.NetworkStats#getNextBucket(android.app.usage.NetworkStats.Bucket) parameter #0:
+ Missing nullability on parameter `bucketOut` in method `getNextBucket`
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetails(int, String, long, long):
+ Missing nullability on method `queryDetails` return
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetails(int, String, long, long) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `queryDetails`
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUid(int, String, long, long, int):
+ Missing nullability on method `queryDetailsForUid` return
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUid(int, String, long, long, int) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `queryDetailsForUid`
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTag(int, String, long, long, int, int):
+ Missing nullability on method `queryDetailsForUidTag` return
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTag(int, String, long, long, int, int) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `queryDetailsForUidTag`
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTagState(int, String, long, long, int, int, int):
+ Missing nullability on method `queryDetailsForUidTagState` return
+MissingNullability: android.app.usage.NetworkStatsManager#queryDetailsForUidTagState(int, String, long, long, int, int, int) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `queryDetailsForUidTagState`
+MissingNullability: android.app.usage.NetworkStatsManager#querySummary(int, String, long, long):
+ Missing nullability on method `querySummary` return
+MissingNullability: android.app.usage.NetworkStatsManager#querySummary(int, String, long, long) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `querySummary`
+MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForDevice(int, String, long, long):
+ Missing nullability on method `querySummaryForDevice` return
+MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForDevice(int, String, long, long) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `querySummaryForDevice`
+MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForUser(int, String, long, long):
+ Missing nullability on method `querySummaryForUser` return
+MissingNullability: android.app.usage.NetworkStatsManager#querySummaryForUser(int, String, long, long) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `querySummaryForUser`
+MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `registerUsageCallback`
+MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback) parameter #3:
+ Missing nullability on parameter `callback` in method `registerUsageCallback`
+MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `registerUsageCallback`
+MissingNullability: android.app.usage.NetworkStatsManager#registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler) parameter #3:
+ Missing nullability on parameter `callback` in method `registerUsageCallback`
+MissingNullability: android.app.usage.NetworkStatsManager#unregisterUsageCallback(android.app.usage.NetworkStatsManager.UsageCallback) parameter #0:
+ Missing nullability on parameter `callback` in method `unregisterUsageCallback`
+MissingNullability: android.app.usage.NetworkStatsManager.UsageCallback#onThresholdReached(int, String) parameter #1:
+ Missing nullability on parameter `subscriberId` in method `onThresholdReached`
+MissingNullability: android.net.IpSecAlgorithm#writeToParcel(android.os.Parcel, int) parameter #0:
+ Missing nullability on parameter `out` in method `writeToParcel`
+MissingNullability: android.net.IpSecManager.UdpEncapsulationSocket#getFileDescriptor():
+ Missing nullability on method `getFileDescriptor` return
+MissingNullability: android.net.TrafficStats#tagDatagramSocket(java.net.DatagramSocket) parameter #0:
+ Missing nullability on parameter `socket` in method `tagDatagramSocket`
+MissingNullability: android.net.TrafficStats#tagFileDescriptor(java.io.FileDescriptor) parameter #0:
+ Missing nullability on parameter `fd` in method `tagFileDescriptor`
+MissingNullability: android.net.TrafficStats#tagSocket(java.net.Socket) parameter #0:
+ Missing nullability on parameter `socket` in method `tagSocket`
+MissingNullability: android.net.TrafficStats#untagDatagramSocket(java.net.DatagramSocket) parameter #0:
+ Missing nullability on parameter `socket` in method `untagDatagramSocket`
+MissingNullability: android.net.TrafficStats#untagFileDescriptor(java.io.FileDescriptor) parameter #0:
+ Missing nullability on parameter `fd` in method `untagFileDescriptor`
+MissingNullability: android.net.TrafficStats#untagSocket(java.net.Socket) parameter #0:
+ Missing nullability on parameter `socket` in method `untagSocket`
+MissingNullability: com.android.internal.util.FileRotator#FileRotator(java.io.File, String, long, long) parameter #0:
+ Missing nullability on parameter `basePath` in method `FileRotator`
+MissingNullability: com.android.internal.util.FileRotator#FileRotator(java.io.File, String, long, long) parameter #1:
+ Missing nullability on parameter `prefix` in method `FileRotator`
+MissingNullability: com.android.internal.util.FileRotator#dumpAll(java.io.OutputStream) parameter #0:
+ Missing nullability on parameter `os` in method `dumpAll`
+MissingNullability: com.android.internal.util.FileRotator#readMatching(com.android.internal.util.FileRotator.Reader, long, long) parameter #0:
+ Missing nullability on parameter `reader` in method `readMatching`
+MissingNullability: com.android.internal.util.FileRotator#rewriteActive(com.android.internal.util.FileRotator.Rewriter, long) parameter #0:
+ Missing nullability on parameter `rewriter` in method `rewriteActive`
+MissingNullability: com.android.internal.util.FileRotator#rewriteAll(com.android.internal.util.FileRotator.Rewriter) parameter #0:
+ Missing nullability on parameter `rewriter` in method `rewriteAll`
+MissingNullability: com.android.internal.util.FileRotator.Reader#read(java.io.InputStream) parameter #0:
+ Missing nullability on parameter `in` in method `read`
+MissingNullability: com.android.internal.util.FileRotator.Writer#write(java.io.OutputStream) parameter #0:
+ Missing nullability on parameter `out` in method `write`
+MissingNullability: com.android.server.NetworkManagementSocketTagger#kernelToTag(String) parameter #0:
+ Missing nullability on parameter `string` in method `kernelToTag`
+MissingNullability: com.android.server.NetworkManagementSocketTagger#tag(java.io.FileDescriptor) parameter #0:
+ Missing nullability on parameter `fd` in method `tag`
+MissingNullability: com.android.server.NetworkManagementSocketTagger#untag(java.io.FileDescriptor) parameter #0:
+ Missing nullability on parameter `fd` in method `untag`
+
+
+RethrowRemoteException: android.app.usage.NetworkStatsManager#queryDetails(int, String, long, long):
+ Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
+RethrowRemoteException: android.app.usage.NetworkStatsManager#querySummary(int, String, long, long):
+ Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
+RethrowRemoteException: android.app.usage.NetworkStatsManager#querySummaryForDevice(int, String, long, long):
+ Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
+RethrowRemoteException: android.app.usage.NetworkStatsManager#querySummaryForUser(int, String, long, long):
+ Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
+
+
+StaticFinalBuilder: android.net.IpSecTransform.Builder:
+ Builder must be final: android.net.IpSecTransform.Builder
+
+
+StaticUtils: android.net.TrafficStats:
+ Fully-static utility classes must not have constructor
+
+
+UseParcelFileDescriptor: android.net.IpSecManager#applyTransportModeTransform(java.io.FileDescriptor, int, android.net.IpSecTransform) parameter #0:
+ Must use ParcelFileDescriptor instead of FileDescriptor in parameter socket in android.net.IpSecManager.applyTransportModeTransform(java.io.FileDescriptor socket, int direction, android.net.IpSecTransform transform)
+UseParcelFileDescriptor: android.net.IpSecManager#removeTransportModeTransforms(java.io.FileDescriptor) parameter #0:
+ Must use ParcelFileDescriptor instead of FileDescriptor in parameter socket in android.net.IpSecManager.removeTransportModeTransforms(java.io.FileDescriptor socket)
+UseParcelFileDescriptor: android.net.IpSecManager.UdpEncapsulationSocket#getFileDescriptor():
+ Must use ParcelFileDescriptor instead of FileDescriptor in method android.net.IpSecManager.UdpEncapsulationSocket.getFileDescriptor()
+UseParcelFileDescriptor: android.net.TrafficStats#tagFileDescriptor(java.io.FileDescriptor) parameter #0:
+ Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in android.net.TrafficStats.tagFileDescriptor(java.io.FileDescriptor fd)
+UseParcelFileDescriptor: android.net.TrafficStats#untagFileDescriptor(java.io.FileDescriptor) parameter #0:
+ Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in android.net.TrafficStats.untagFileDescriptor(java.io.FileDescriptor fd)
+UseParcelFileDescriptor: com.android.server.NetworkManagementSocketTagger#tag(java.io.FileDescriptor) parameter #0:
+ Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in com.android.server.NetworkManagementSocketTagger.tag(java.io.FileDescriptor fd)
+UseParcelFileDescriptor: com.android.server.NetworkManagementSocketTagger#untag(java.io.FileDescriptor) parameter #0:
+ Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in com.android.server.NetworkManagementSocketTagger.untag(java.io.FileDescriptor fd)
diff --git a/framework-t/api/module-lib-current.txt b/framework-t/api/module-lib-current.txt
index 2ff3451..59ca730 100644
--- a/framework-t/api/module-lib-current.txt
+++ b/framework-t/api/module-lib-current.txt
@@ -1,4 +1,30 @@
// Signature format: 2.0
+package android.app.usage {
+
+ public class NetworkStatsManager {
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void forceUpdate();
+ method public static int getCollapsedRatType(int);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyNetworkStatus(@NonNull java.util.List<android.net.Network>, @NonNull java.util.List<android.net.NetworkStateSnapshot>, @Nullable String, @NonNull java.util.List<android.net.UnderlyingNetworkInfo>);
+ method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForDevice(@NonNull android.net.NetworkTemplate, long, long);
+ method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(@NonNull android.net.NetworkTemplate, long, long, int, int, int) throws java.lang.SecurityException;
+ method @NonNull @WorkerThread public android.app.usage.NetworkStats querySummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException;
+ method @NonNull @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(@NonNull android.net.NetworkTemplate, long, long);
+ method @NonNull @WorkerThread public android.app.usage.NetworkStats queryTaggedSummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException;
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}, conditional=true) public void registerUsageCallback(@NonNull android.net.NetworkTemplate, long, @NonNull java.util.concurrent.Executor, @NonNull android.app.usage.NetworkStatsManager.UsageCallback);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setDefaultGlobalAlert(long);
+ method public void setPollForce(boolean);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setPollOnOpen(boolean);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setStatsProviderWarningAndLimitAsync(@NonNull String, long, long);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setUidForeground(int, boolean);
+ field public static final int NETWORK_TYPE_5G_NSA = -2; // 0xfffffffe
+ }
+
+ public abstract static class NetworkStatsManager.UsageCallback {
+ method public void onThresholdReached(@NonNull android.net.NetworkTemplate);
+ }
+
+}
+
package android.net {
public final class ConnectivityFrameworkInitializerTiramisu {
@@ -13,5 +39,138 @@
method public int getResourceId();
}
+ public class NetworkIdentity {
+ method public int getOemManaged();
+ method public int getRatType();
+ method public int getSubId();
+ method @Nullable public String getSubscriberId();
+ method public int getType();
+ method @Nullable public String getWifiNetworkKey();
+ method public boolean isDefaultNetwork();
+ method public boolean isMetered();
+ method public boolean isRoaming();
+ }
+
+ public static final class NetworkIdentity.Builder {
+ ctor public NetworkIdentity.Builder();
+ method @NonNull public android.net.NetworkIdentity build();
+ method @NonNull public android.net.NetworkIdentity.Builder clearRatType();
+ method @NonNull public android.net.NetworkIdentity.Builder setDefaultNetwork(boolean);
+ method @NonNull public android.net.NetworkIdentity.Builder setMetered(boolean);
+ method @NonNull public android.net.NetworkIdentity.Builder setNetworkStateSnapshot(@NonNull android.net.NetworkStateSnapshot);
+ method @NonNull public android.net.NetworkIdentity.Builder setOemManaged(int);
+ method @NonNull public android.net.NetworkIdentity.Builder setRatType(int);
+ method @NonNull public android.net.NetworkIdentity.Builder setRoaming(boolean);
+ method @NonNull public android.net.NetworkIdentity.Builder setSubId(int);
+ method @NonNull public android.net.NetworkIdentity.Builder setSubscriberId(@Nullable String);
+ method @NonNull public android.net.NetworkIdentity.Builder setType(int);
+ method @NonNull public android.net.NetworkIdentity.Builder setWifiNetworkKey(@Nullable String);
+ }
+
+ public final class NetworkStateSnapshot implements android.os.Parcelable {
+ ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
+ method public int describeContents();
+ method public int getLegacyType();
+ method @NonNull public android.net.LinkProperties getLinkProperties();
+ method @NonNull public android.net.Network getNetwork();
+ method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
+ method public int getSubId();
+ method @Deprecated @Nullable public String getSubscriberId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR;
+ }
+
+ public class NetworkStatsCollection {
+ method @NonNull public java.util.Map<android.net.NetworkStatsCollection.Key,android.net.NetworkStatsHistory> getEntries();
+ }
+
+ public static final class NetworkStatsCollection.Builder {
+ ctor public NetworkStatsCollection.Builder(long);
+ method @NonNull public android.net.NetworkStatsCollection.Builder addEntry(@NonNull android.net.NetworkStatsCollection.Key, @NonNull android.net.NetworkStatsHistory);
+ method @NonNull public android.net.NetworkStatsCollection build();
+ }
+
+ public static class NetworkStatsCollection.Key {
+ ctor public NetworkStatsCollection.Key(@NonNull java.util.Set<android.net.NetworkIdentity>, int, int, int);
+ }
+
+ public final class NetworkStatsHistory implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<android.net.NetworkStatsHistory.Entry> getEntries();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStatsHistory> CREATOR;
+ }
+
+ public static final class NetworkStatsHistory.Builder {
+ ctor public NetworkStatsHistory.Builder(long, int);
+ method @NonNull public android.net.NetworkStatsHistory.Builder addEntry(@NonNull android.net.NetworkStatsHistory.Entry);
+ method @NonNull public android.net.NetworkStatsHistory build();
+ }
+
+ public static final class NetworkStatsHistory.Entry {
+ ctor public NetworkStatsHistory.Entry(long, long, long, long, long, long, long);
+ method public long getActiveTime();
+ method public long getBucketStart();
+ method public long getOperations();
+ method public long getRxBytes();
+ method public long getRxPackets();
+ method public long getTxBytes();
+ method public long getTxPackets();
+ }
+
+ public final class NetworkTemplate implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getDefaultNetworkStatus();
+ method public int getMatchRule();
+ method public int getMeteredness();
+ method public int getOemManaged();
+ method public int getRatType();
+ method public int getRoaming();
+ method @NonNull public java.util.Set<java.lang.String> getSubscriberIds();
+ method @NonNull public java.util.Set<java.lang.String> getWifiNetworkKeys();
+ method public boolean matches(@NonNull android.net.NetworkIdentity);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkTemplate> CREATOR;
+ field public static final int MATCH_BLUETOOTH = 8; // 0x8
+ field public static final int MATCH_CARRIER = 10; // 0xa
+ field public static final int MATCH_ETHERNET = 5; // 0x5
+ field public static final int MATCH_MOBILE = 1; // 0x1
+ field public static final int MATCH_PROXY = 9; // 0x9
+ field public static final int MATCH_WIFI = 4; // 0x4
+ field public static final int NETWORK_TYPE_ALL = -1; // 0xffffffff
+ field public static final int OEM_MANAGED_ALL = -1; // 0xffffffff
+ field public static final int OEM_MANAGED_NO = 0; // 0x0
+ field public static final int OEM_MANAGED_PAID = 1; // 0x1
+ field public static final int OEM_MANAGED_PRIVATE = 2; // 0x2
+ field public static final int OEM_MANAGED_YES = -2; // 0xfffffffe
+ }
+
+ public static final class NetworkTemplate.Builder {
+ ctor public NetworkTemplate.Builder(int);
+ method @NonNull public android.net.NetworkTemplate build();
+ method @NonNull public android.net.NetworkTemplate.Builder setDefaultNetworkStatus(int);
+ method @NonNull public android.net.NetworkTemplate.Builder setMeteredness(int);
+ method @NonNull public android.net.NetworkTemplate.Builder setOemManaged(int);
+ method @NonNull public android.net.NetworkTemplate.Builder setRatType(int);
+ method @NonNull public android.net.NetworkTemplate.Builder setRoaming(int);
+ method @NonNull public android.net.NetworkTemplate.Builder setSubscriberIds(@NonNull java.util.Set<java.lang.String>);
+ method @NonNull public android.net.NetworkTemplate.Builder setWifiNetworkKeys(@NonNull java.util.Set<java.lang.String>);
+ }
+
+ public class TrafficStats {
+ method public static void attachSocketTagger();
+ method public static void init(@NonNull android.content.Context);
+ }
+
+ public final class UnderlyingNetworkInfo implements android.os.Parcelable {
+ ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>);
+ method public int describeContents();
+ method @NonNull public String getInterface();
+ method public int getOwnerUid();
+ method @NonNull public java.util.List<java.lang.String> getUnderlyingInterfaces();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.UnderlyingNetworkInfo> CREATOR;
+ }
+
}
diff --git a/framework-t/api/module-lib-lint-baseline.txt b/framework-t/api/module-lib-lint-baseline.txt
new file mode 100644
index 0000000..3158bd4
--- /dev/null
+++ b/framework-t/api/module-lib-lint-baseline.txt
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+BannedThrow: android.app.usage.NetworkStatsManager#queryDetailsForUidTagState(android.net.NetworkTemplate, long, long, int, int, int):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#querySummary(android.net.NetworkTemplate, long, long):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
+BannedThrow: android.app.usage.NetworkStatsManager#queryTaggedSummary(android.net.NetworkTemplate, long, long):
+ Methods must not mention RuntimeException subclasses in throws clauses (was `java.lang.SecurityException`)
diff --git a/framework-t/api/removed.txt b/framework-t/api/removed.txt
index d802177..1ba87d8 100644
--- a/framework-t/api/removed.txt
+++ b/framework-t/api/removed.txt
@@ -1 +1,9 @@
// Signature format: 2.0
+package android.net {
+
+ public class TrafficStats {
+ method @Deprecated public static void setThreadStatsUidSelf();
+ }
+
+}
+
diff --git a/framework-t/api/system-current.txt b/framework-t/api/system-current.txt
index 041bcaf..cc8f6b2 100644
--- a/framework-t/api/system-current.txt
+++ b/framework-t/api/system-current.txt
@@ -1,4 +1,499 @@
// Signature format: 2.0
+package android.app.usage {
+
+ public class NetworkStatsManager {
+ method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.net.NetworkStats getMobileUidStats();
+ method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public android.net.NetworkStats getWifiUidStats();
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
+ }
+
+}
+
+package android.nearby {
+
+ public interface BroadcastCallback {
+ method public void onStatus(int);
+ field public static final int STATUS_FAILURE = 1; // 0x1
+ field public static final int STATUS_FAILURE_ALREADY_REGISTERED = 2; // 0x2
+ field public static final int STATUS_FAILURE_MISSING_PERMISSIONS = 4; // 0x4
+ field public static final int STATUS_FAILURE_SIZE_EXCEED_LIMIT = 3; // 0x3
+ field public static final int STATUS_OK = 0; // 0x0
+ }
+
+ public abstract class BroadcastRequest implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<java.lang.Integer> getMediums();
+ method @IntRange(from=0xffffff81, to=126) public int getTxPower();
+ method public int getType();
+ method public int getVersion();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int BROADCAST_TYPE_NEARBY_PRESENCE = 3; // 0x3
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.BroadcastRequest> CREATOR;
+ field public static final int PRESENCE_VERSION_V0 = 0; // 0x0
+ field public static final int PRESENCE_VERSION_V1 = 1; // 0x1
+ field public static final int UNKNOWN_TX_POWER = -100; // 0xffffff9c
+ }
+
+ public final class CredentialElement implements android.os.Parcelable {
+ ctor public CredentialElement(@NonNull String, @NonNull byte[]);
+ method public int describeContents();
+ method @NonNull public String getKey();
+ method @NonNull public byte[] getValue();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.CredentialElement> CREATOR;
+ }
+
+ public final class DataElement implements android.os.Parcelable {
+ ctor public DataElement(int, @NonNull byte[]);
+ method public int describeContents();
+ method public int getKey();
+ method @NonNull public byte[] getValue();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.DataElement> CREATOR;
+ }
+
+ public class FastPairAccountKeyDeviceMetadata {
+ method @Nullable public byte[] getAccountKey();
+ method @Nullable public android.nearby.FastPairDeviceMetadata getFastPairDeviceMetadata();
+ method @Nullable public android.nearby.FastPairDiscoveryItem getFastPairDiscoveryItem();
+ method @Nullable public byte[] getSha256AccountKeyPublicAddress();
+ }
+
+ public static final class FastPairAccountKeyDeviceMetadata.Builder {
+ ctor public FastPairAccountKeyDeviceMetadata.Builder();
+ method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata build();
+ method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setAccountKey(@Nullable byte[]);
+ method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setFastPairDeviceMetadata(@Nullable android.nearby.FastPairDeviceMetadata);
+ method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setFastPairDiscoveryItem(@Nullable android.nearby.FastPairDiscoveryItem);
+ method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata.Builder setSha256AccountKeyPublicAddress(@Nullable byte[]);
+ }
+
+ public class FastPairAntispoofkeyDeviceMetadata {
+ }
+
+ public static final class FastPairAntispoofkeyDeviceMetadata.Builder {
+ ctor public FastPairAntispoofkeyDeviceMetadata.Builder();
+ method @NonNull public android.nearby.FastPairAntispoofkeyDeviceMetadata build();
+ method @NonNull public android.nearby.FastPairAntispoofkeyDeviceMetadata.Builder setAntiSpoofPublicKey(@Nullable byte[]);
+ method @NonNull public android.nearby.FastPairAntispoofkeyDeviceMetadata.Builder setFastPairDeviceMetadata(@Nullable android.nearby.FastPairDeviceMetadata);
+ }
+
+ public abstract class FastPairDataProviderBase {
+ ctor public FastPairDataProviderBase(@NonNull String);
+ method @Nullable public final android.os.IBinder getBinder();
+ method public abstract void onLoadFastPairAccountDevicesMetadata(@NonNull android.nearby.FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairAccountDevicesMetadataCallback);
+ method public abstract void onLoadFastPairAntispoofkeyDeviceMetadata(@NonNull android.nearby.FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataCallback);
+ method public abstract void onLoadFastPairEligibleAccounts(@NonNull android.nearby.FastPairDataProviderBase.FastPairEligibleAccountsRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairEligibleAccountsCallback);
+ method public abstract void onManageFastPairAccount(@NonNull android.nearby.FastPairDataProviderBase.FastPairManageAccountRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairManageActionCallback);
+ method public abstract void onManageFastPairAccountDevice(@NonNull android.nearby.FastPairDataProviderBase.FastPairManageAccountDeviceRequest, @NonNull android.nearby.FastPairDataProviderBase.FastPairManageActionCallback);
+ field public static final String ACTION_FAST_PAIR_DATA_PROVIDER = "android.nearby.action.FAST_PAIR_DATA_PROVIDER";
+ field public static final int ERROR_CODE_BAD_REQUEST = 0; // 0x0
+ field public static final int ERROR_CODE_INTERNAL_ERROR = 1; // 0x1
+ field public static final int MANAGE_REQUEST_ADD = 0; // 0x0
+ field public static final int MANAGE_REQUEST_REMOVE = 1; // 0x1
+ }
+
+ public static interface FastPairDataProviderBase.FastPairAccountDevicesMetadataCallback {
+ method public void onError(int, @Nullable String);
+ method public void onFastPairAccountDevicesMetadataReceived(@NonNull java.util.Collection<android.nearby.FastPairAccountKeyDeviceMetadata>);
+ }
+
+ public static class FastPairDataProviderBase.FastPairAccountDevicesMetadataRequest {
+ method @NonNull public android.accounts.Account getAccount();
+ }
+
+ public static interface FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataCallback {
+ method public void onError(int, @Nullable String);
+ method public void onFastPairAntispoofkeyDeviceMetadataReceived(@NonNull android.nearby.FastPairAntispoofkeyDeviceMetadata);
+ }
+
+ public static class FastPairDataProviderBase.FastPairAntispoofkeyDeviceMetadataRequest {
+ method @NonNull public byte[] getModelId();
+ }
+
+ public static interface FastPairDataProviderBase.FastPairEligibleAccountsCallback {
+ method public void onError(int, @Nullable String);
+ method public void onFastPairEligibleAccountsReceived(@NonNull java.util.Collection<android.nearby.FastPairEligibleAccount>);
+ }
+
+ public static class FastPairDataProviderBase.FastPairEligibleAccountsRequest {
+ }
+
+ public static class FastPairDataProviderBase.FastPairManageAccountDeviceRequest {
+ method @NonNull public android.accounts.Account getAccount();
+ method @NonNull public android.nearby.FastPairAccountKeyDeviceMetadata getAccountKeyDeviceMetadata();
+ method @Nullable public String getBleAddress();
+ method public int getRequestType();
+ }
+
+ public static class FastPairDataProviderBase.FastPairManageAccountRequest {
+ method @NonNull public android.accounts.Account getAccount();
+ method public int getRequestType();
+ }
+
+ public static interface FastPairDataProviderBase.FastPairManageActionCallback {
+ method public void onError(int, @Nullable String);
+ method public void onSuccess();
+ }
+
+ public class FastPairDeviceMetadata {
+ method @Nullable public String getAssistantSetupHalfSheet();
+ method @Nullable public String getAssistantSetupNotification();
+ method public int getBleTxPower();
+ method @Nullable public String getConfirmPinDescription();
+ method @Nullable public String getConfirmPinTitle();
+ method @Nullable public String getConnectSuccessCompanionAppInstalled();
+ method @Nullable public String getConnectSuccessCompanionAppNotInstalled();
+ method public int getDeviceType();
+ method @Nullable public String getDownloadCompanionAppDescription();
+ method @Nullable public String getFailConnectGoToSettingsDescription();
+ method @Nullable public String getFastPairTvConnectDeviceNoAccountDescription();
+ method @Nullable public byte[] getImage();
+ method @Nullable public String getImageUrl();
+ method @Nullable public String getInitialNotificationDescription();
+ method @Nullable public String getInitialNotificationDescriptionNoAccount();
+ method @Nullable public String getInitialPairingDescription();
+ method @Nullable public String getIntentUri();
+ method @Nullable public String getLocale();
+ method @Nullable public String getName();
+ method @Nullable public String getOpenCompanionAppDescription();
+ method @Nullable public String getRetroactivePairingDescription();
+ method @Nullable public String getSubsequentPairingDescription();
+ method @Nullable public String getSyncContactsDescription();
+ method @Nullable public String getSyncContactsTitle();
+ method @Nullable public String getSyncSmsDescription();
+ method @Nullable public String getSyncSmsTitle();
+ method public float getTriggerDistance();
+ method @Nullable public String getTrueWirelessImageUrlCase();
+ method @Nullable public String getTrueWirelessImageUrlLeftBud();
+ method @Nullable public String getTrueWirelessImageUrlRightBud();
+ method @Nullable public String getUnableToConnectDescription();
+ method @Nullable public String getUnableToConnectTitle();
+ method @Nullable public String getUpdateCompanionAppDescription();
+ method @Nullable public String getWaitLaunchCompanionAppDescription();
+ }
+
+ public static final class FastPairDeviceMetadata.Builder {
+ ctor public FastPairDeviceMetadata.Builder();
+ method @NonNull public android.nearby.FastPairDeviceMetadata build();
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setAssistantSetupHalfSheet(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setAssistantSetupNotification(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setBleTxPower(int);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConfirmPinDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConfirmPinTitle(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConnectSuccessCompanionAppInstalled(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setConnectSuccessCompanionAppNotInstalled(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setDeviceType(int);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setDownloadCompanionAppDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setFailConnectGoToSettingsDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setFastPairTvConnectDeviceNoAccountDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setImage(@Nullable byte[]);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setImageUrl(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setInitialNotificationDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setInitialNotificationDescriptionNoAccount(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setInitialPairingDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setIntentUri(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setLocale(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setName(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setOpenCompanionAppDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setRetroactivePairingDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSubsequentPairingDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncContactsDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncContactsTitle(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncSmsDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setSyncSmsTitle(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTriggerDistance(float);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTrueWirelessImageUrlCase(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTrueWirelessImageUrlLeftBud(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setTrueWirelessImageUrlRightBud(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setUnableToConnectDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setUnableToConnectTitle(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setUpdateCompanionAppDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDeviceMetadata.Builder setWaitLaunchCompanionAppDescription(@Nullable String);
+ }
+
+ public class FastPairDiscoveryItem {
+ method @Nullable public String getActionUrl();
+ method public int getActionUrlType();
+ method @Nullable public String getAppName();
+ method public int getAttachmentType();
+ method @Nullable public byte[] getAuthenticationPublicKeySecp256r1();
+ method @Nullable public byte[] getBleRecordBytes();
+ method public int getDebugCategory();
+ method @Nullable public String getDebugMessage();
+ method @Nullable public String getDescription();
+ method @Nullable public String getDeviceName();
+ method @Nullable public String getDisplayUrl();
+ method @Nullable public String getEntityId();
+ method @Nullable public String getFeatureGraphicUrl();
+ method public long getFirstObservationTimestampMillis();
+ method @Nullable public String getGroupId();
+ method @Nullable public String getIconFfeUrl();
+ method @Nullable public byte[] getIconPng();
+ method @Nullable public String getId();
+ method public long getLastObservationTimestampMillis();
+ method public int getLastUserExperience();
+ method public long getLostMillis();
+ method @Nullable public String getMacAddress();
+ method @Nullable public String getPackageName();
+ method public long getPendingAppInstallTimestampMillis();
+ method public int getRssi();
+ method public int getState();
+ method @Nullable public String getTitle();
+ method @Nullable public String getTriggerId();
+ method public int getTxPower();
+ method public int getType();
+ }
+
+ public static final class FastPairDiscoveryItem.Builder {
+ ctor public FastPairDiscoveryItem.Builder();
+ method @NonNull public android.nearby.FastPairDiscoveryItem build();
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setActionUrl(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setActionUrlType(int);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setAppName(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setAttachmentType(int);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setAuthenticationPublicKeySecp256r1(@Nullable byte[]);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setBleRecordBytes(@Nullable byte[]);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDebugCategory(int);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDebugMessage(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDescription(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDeviceName(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setDisplayUrl(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setEntityId(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setFeatureGraphicUrl(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setFirstObservationTimestampMillis(long);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setGroupId(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setIconFfeUrl(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setIconPng(@Nullable byte[]);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setId(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setLastObservationTimestampMillis(long);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setLastUserExperience(int);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setLostMillis(long);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setMacAddress(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setPackageName(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setPendingAppInstallTimestampMillis(long);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setRssi(int);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setState(int);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setTitle(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setTriggerId(@Nullable String);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setTxPower(int);
+ method @NonNull public android.nearby.FastPairDiscoveryItem.Builder setType(int);
+ }
+
+ public class FastPairEligibleAccount {
+ }
+
+ public static final class FastPairEligibleAccount.Builder {
+ ctor public FastPairEligibleAccount.Builder();
+ method @NonNull public android.nearby.FastPairEligibleAccount build();
+ method @NonNull public android.nearby.FastPairEligibleAccount.Builder setAccount(@Nullable android.accounts.Account);
+ method @NonNull public android.nearby.FastPairEligibleAccount.Builder setOptIn(boolean);
+ }
+
+ public abstract class NearbyDevice {
+ method @NonNull public java.util.List<java.lang.Integer> getMediums();
+ method @Nullable public String getName();
+ method @IntRange(from=0xffffff81, to=126) public int getRssi();
+ method public static boolean isValidMedium(int);
+ }
+
+ public final class NearbyDeviceParcelable implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getBluetoothAddress();
+ method @Nullable public byte[] getData();
+ method @Nullable public String getFastPairModelId();
+ method public int getMedium();
+ method @Nullable public String getName();
+ method @IntRange(from=0xffffff81, to=126) public int getRssi();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.NearbyDeviceParcelable> CREATOR;
+ }
+
+ public static final class NearbyDeviceParcelable.Builder {
+ ctor public NearbyDeviceParcelable.Builder();
+ method @NonNull public android.nearby.NearbyDeviceParcelable build();
+ method @NonNull public android.nearby.NearbyDeviceParcelable.Builder setBluetoothAddress(@Nullable String);
+ method @NonNull public android.nearby.NearbyDeviceParcelable.Builder setData(@Nullable byte[]);
+ method @NonNull public android.nearby.NearbyDeviceParcelable.Builder setFastPairModelId(@Nullable String);
+ method @NonNull public android.nearby.NearbyDeviceParcelable.Builder setMedium(int);
+ method @NonNull public android.nearby.NearbyDeviceParcelable.Builder setName(@Nullable String);
+ method @NonNull public android.nearby.NearbyDeviceParcelable.Builder setRssi(int);
+ }
+
+ public final class NearbyFrameworkInitializer {
+ method public static void registerServiceWrappers();
+ }
+
+ public class NearbyManager {
+ method public void startBroadcast(@NonNull android.nearby.BroadcastRequest, @NonNull java.util.concurrent.Executor, @NonNull android.nearby.BroadcastCallback);
+ method public void startScan(@NonNull android.nearby.ScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.nearby.ScanCallback);
+ method public void stopBroadcast(@NonNull android.nearby.BroadcastCallback);
+ method public void stopScan(@NonNull android.nearby.ScanCallback);
+ }
+
+ public final class PresenceBroadcastRequest extends android.nearby.BroadcastRequest implements android.os.Parcelable {
+ method @NonNull public java.util.List<java.lang.Integer> getActions();
+ method @NonNull public android.nearby.PrivateCredential getCredential();
+ method @NonNull public java.util.List<android.nearby.DataElement> getExtendedProperties();
+ method @NonNull public byte[] getSalt();
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PresenceBroadcastRequest> CREATOR;
+ }
+
+ public static final class PresenceBroadcastRequest.Builder {
+ ctor public PresenceBroadcastRequest.Builder(@NonNull java.util.List<java.lang.Integer>, @NonNull byte[]);
+ method @NonNull public android.nearby.PresenceBroadcastRequest.Builder addAction(@IntRange(from=1, to=255) int);
+ method @NonNull public android.nearby.PresenceBroadcastRequest.Builder addExtendedProperty(@NonNull android.nearby.DataElement);
+ method @NonNull public android.nearby.PresenceBroadcastRequest build();
+ method @NonNull public android.nearby.PresenceBroadcastRequest.Builder setCredential(@NonNull android.nearby.PrivateCredential);
+ method @NonNull public android.nearby.PresenceBroadcastRequest.Builder setTxPower(@IntRange(from=0xffffff81, to=126) int);
+ method @NonNull public android.nearby.PresenceBroadcastRequest.Builder setVersion(int);
+ }
+
+ public abstract class PresenceCredential implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public byte[] getAuthenticityKey();
+ method @NonNull public java.util.List<android.nearby.CredentialElement> getCredentialElements();
+ method public int getIdentityType();
+ method @NonNull public byte[] getSecretId();
+ method public int getType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PresenceCredential> CREATOR;
+ field public static final int CREDENTIAL_TYPE_PRIVATE = 0; // 0x0
+ field public static final int CREDENTIAL_TYPE_PUBLIC = 1; // 0x1
+ field public static final int IDENTITY_TYPE_PRIVATE = 1; // 0x1
+ field public static final int IDENTITY_TYPE_PROVISIONED = 2; // 0x2
+ field public static final int IDENTITY_TYPE_PUBLIC = 4; // 0x4
+ field public static final int IDENTITY_TYPE_TRUSTED = 3; // 0x3
+ field public static final int IDENTITY_TYPE_UNKNOWN = 0; // 0x0
+ }
+
+ public final class PresenceDevice extends android.nearby.NearbyDevice implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public String getDeviceId();
+ method @Nullable public String getDeviceImageUrl();
+ method public int getDeviceType();
+ method public long getDiscoveryTimestampMillis();
+ method @NonNull public byte[] getEncryptedIdentity();
+ method @NonNull public java.util.List<android.nearby.DataElement> getExtendedProperties();
+ method @NonNull public byte[] getSalt();
+ method @NonNull public byte[] getSecretId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PresenceDevice> CREATOR;
+ }
+
+ public static final class PresenceDevice.Builder {
+ ctor public PresenceDevice.Builder();
+ method @NonNull public android.nearby.PresenceDevice.Builder addExtendedProperty(@NonNull android.nearby.DataElement);
+ method @NonNull public android.nearby.PresenceDevice.Builder addMedium(int);
+ method @NonNull public android.nearby.PresenceDevice build();
+ method @NonNull public android.nearby.PresenceDevice.Builder setDeviceId(@NonNull String);
+ method @NonNull public android.nearby.PresenceDevice.Builder setDeviceImageUrl(@Nullable String);
+ method @NonNull public android.nearby.PresenceDevice.Builder setDeviceType(int);
+ method @NonNull public android.nearby.PresenceDevice.Builder setDiscoveryTimestampMillis(long);
+ method @NonNull public android.nearby.PresenceDevice.Builder setEncryptedIdentity(@NonNull byte[]);
+ method @NonNull public android.nearby.PresenceDevice.Builder setName(@Nullable String);
+ method @NonNull public android.nearby.PresenceDevice.Builder setRssi(int);
+ method @NonNull public android.nearby.PresenceDevice.Builder setSalt(@NonNull byte[]);
+ method @NonNull public android.nearby.PresenceDevice.Builder setSecretId(@NonNull byte[]);
+ }
+
+ public final class PresenceScanFilter extends android.nearby.ScanFilter implements android.os.Parcelable {
+ method @NonNull public java.util.List<android.nearby.PublicCredential> getCredentials();
+ method @NonNull public java.util.List<android.nearby.DataElement> getExtendedProperties();
+ method @NonNull public java.util.List<java.lang.Integer> getPresenceActions();
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PresenceScanFilter> CREATOR;
+ }
+
+ public static final class PresenceScanFilter.Builder {
+ ctor public PresenceScanFilter.Builder();
+ method @NonNull public android.nearby.PresenceScanFilter.Builder addCredential(@NonNull android.nearby.PublicCredential);
+ method @NonNull public android.nearby.PresenceScanFilter.Builder addExtendedProperty(@NonNull android.nearby.DataElement);
+ method @NonNull public android.nearby.PresenceScanFilter.Builder addPresenceAction(@IntRange(from=1, to=255) int);
+ method @NonNull public android.nearby.PresenceScanFilter build();
+ method @NonNull public android.nearby.PresenceScanFilter.Builder setMaxPathLoss(@IntRange(from=0, to=127) int);
+ }
+
+ public final class PrivateCredential extends android.nearby.PresenceCredential implements android.os.Parcelable {
+ method @NonNull public String getDeviceName();
+ method @NonNull public byte[] getMetadataEncryptionKey();
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PrivateCredential> CREATOR;
+ }
+
+ public static final class PrivateCredential.Builder {
+ ctor public PrivateCredential.Builder(@NonNull byte[], @NonNull byte[]);
+ method @NonNull public android.nearby.PrivateCredential.Builder addCredentialElement(@NonNull android.nearby.CredentialElement);
+ method @NonNull public android.nearby.PrivateCredential build();
+ method @NonNull public android.nearby.PrivateCredential.Builder setDeviceName(@NonNull String);
+ method @NonNull public android.nearby.PrivateCredential.Builder setIdentityType(int);
+ method @NonNull public android.nearby.PrivateCredential.Builder setMetadataEncryptionKey(@NonNull byte[]);
+ }
+
+ public final class PublicCredential extends android.nearby.PresenceCredential implements android.os.Parcelable {
+ method @NonNull public byte[] getEncryptedMetadata();
+ method @NonNull public byte[] getEncryptedMetadataKeyTag();
+ method @NonNull public byte[] getPublicKey();
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.PublicCredential> CREATOR;
+ }
+
+ public static final class PublicCredential.Builder {
+ ctor public PublicCredential.Builder(@NonNull byte[], @NonNull byte[]);
+ method @NonNull public android.nearby.PublicCredential.Builder addCredentialElement(@NonNull android.nearby.CredentialElement);
+ method @NonNull public android.nearby.PublicCredential build();
+ method @NonNull public android.nearby.PublicCredential.Builder setEncryptedMetadata(@NonNull byte[]);
+ method @NonNull public android.nearby.PublicCredential.Builder setEncryptedMetadataKeyTag(@NonNull byte[]);
+ method @NonNull public android.nearby.PublicCredential.Builder setIdentityType(int);
+ method @NonNull public android.nearby.PublicCredential.Builder setPublicKey(@NonNull byte[]);
+ }
+
+ public interface ScanCallback {
+ method public void onDiscovered(@NonNull android.nearby.NearbyDevice);
+ method public void onLost(@NonNull android.nearby.NearbyDevice);
+ method public void onUpdated(@NonNull android.nearby.NearbyDevice);
+ }
+
+ public abstract class ScanFilter implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0, to=127) public int getMaxPathLoss();
+ method public int getType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.ScanFilter> CREATOR;
+ }
+
+ public final class ScanRequest implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<android.nearby.ScanFilter> getScanFilters();
+ method public int getScanMode();
+ method public int getScanType();
+ method @NonNull public android.os.WorkSource getWorkSource();
+ method public boolean isEnableBle();
+ method public static boolean isValidScanMode(int);
+ method public static boolean isValidScanType(int);
+ method @NonNull public static String scanModeToString(int);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nearby.ScanRequest> CREATOR;
+ field public static final int SCAN_MODE_BALANCED = 1; // 0x1
+ field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
+ field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
+ field public static final int SCAN_MODE_NO_POWER = -1; // 0xffffffff
+ field public static final int SCAN_TYPE_EXPOSURE_NOTIFICATION = 4; // 0x4
+ field public static final int SCAN_TYPE_FAST_PAIR = 1; // 0x1
+ field public static final int SCAN_TYPE_NEARBY_PRESENCE = 3; // 0x3
+ field public static final int SCAN_TYPE_NEARBY_SHARE = 2; // 0x2
+ }
+
+ public static final class ScanRequest.Builder {
+ ctor public ScanRequest.Builder();
+ method @NonNull public android.nearby.ScanRequest.Builder addScanFilter(@NonNull android.nearby.ScanFilter);
+ method @NonNull public android.nearby.ScanRequest build();
+ method @NonNull public android.nearby.ScanRequest.Builder setEnableBle(boolean);
+ method @NonNull public android.nearby.ScanRequest.Builder setScanMode(int);
+ method @NonNull public android.nearby.ScanRequest.Builder setScanType(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.nearby.ScanRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
+ }
+
+}
+
package android.net {
public class IpSecManager {
@@ -18,5 +513,77 @@
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecTransform buildTunnelModeTransform(@NonNull java.net.InetAddress, @NonNull android.net.IpSecManager.SecurityParameterIndex) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
}
+ public final class NetworkStats implements java.lang.Iterable<android.net.NetworkStats.Entry> android.os.Parcelable {
+ ctor public NetworkStats(long, int);
+ method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats);
+ method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry);
+ method public int describeContents();
+ method @NonNull public java.util.Iterator<android.net.NetworkStats.Entry> iterator();
+ method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats);
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR;
+ field public static final int DEFAULT_NETWORK_ALL = -1; // 0xffffffff
+ field public static final int DEFAULT_NETWORK_NO = 0; // 0x0
+ field public static final int DEFAULT_NETWORK_YES = 1; // 0x1
+ field public static final String IFACE_VT = "vt_data0";
+ field public static final int METERED_ALL = -1; // 0xffffffff
+ field public static final int METERED_NO = 0; // 0x0
+ field public static final int METERED_YES = 1; // 0x1
+ field public static final int ROAMING_ALL = -1; // 0xffffffff
+ field public static final int ROAMING_NO = 0; // 0x0
+ field public static final int ROAMING_YES = 1; // 0x1
+ field public static final int SET_ALL = -1; // 0xffffffff
+ field public static final int SET_DEFAULT = 0; // 0x0
+ field public static final int SET_FOREGROUND = 1; // 0x1
+ field public static final int TAG_NONE = 0; // 0x0
+ field public static final int UID_ALL = -1; // 0xffffffff
+ field public static final int UID_TETHERING = -5; // 0xfffffffb
+ }
+
+ public static class NetworkStats.Entry {
+ ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long);
+ method public int getDefaultNetwork();
+ method public int getMetered();
+ method public long getOperations();
+ method public int getRoaming();
+ method public long getRxBytes();
+ method public long getRxPackets();
+ method public int getSet();
+ method public int getTag();
+ method public long getTxBytes();
+ method public long getTxPackets();
+ method public int getUid();
+ }
+
+ public class TrafficStats {
+ method public static void setThreadStatsTagApp();
+ method public static void setThreadStatsTagBackup();
+ method public static void setThreadStatsTagDownload();
+ method public static void setThreadStatsTagRestore();
+ field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = -113; // 0xffffff8f
+ field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = -128; // 0xffffff80
+ field public static final int TAG_NETWORK_STACK_RANGE_END = -257; // 0xfffffeff
+ field public static final int TAG_NETWORK_STACK_RANGE_START = -768; // 0xfffffd00
+ field public static final int TAG_SYSTEM_IMPERSONATION_RANGE_END = -241; // 0xffffff0f
+ field public static final int TAG_SYSTEM_IMPERSONATION_RANGE_START = -256; // 0xffffff00
+ }
+
+}
+
+package android.net.netstats.provider {
+
+ public abstract class NetworkStatsProvider {
+ ctor public NetworkStatsProvider();
+ method public void notifyAlertReached();
+ method public void notifyLimitReached();
+ method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
+ method public void notifyWarningReached();
+ method public abstract void onRequestStatsUpdate(int);
+ method public abstract void onSetAlert(long);
+ method public abstract void onSetLimit(@NonNull String, long);
+ method public void onSetWarningAndLimit(@NonNull String, long, long);
+ field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff
+ }
+
}
diff --git a/framework/Android.bp b/framework/Android.bp
index da16a8d..66b662b 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -63,6 +63,7 @@
srcs: [
":framework-connectivity-sources",
":net-utils-framework-common-srcs",
+ ":framework-connectivity-api-shared-srcs",
],
aidl: {
generate_get_transaction_name: true,
@@ -76,7 +77,7 @@
],
},
stub_only_libs: [
- "framework-connectivity-tiramisu.stubs.module_lib",
+ "framework-connectivity-t.stubs.module_lib",
],
impl_only_libs: [
"framework-tethering.stubs.module_lib",
@@ -84,11 +85,12 @@
"net-utils-device-common",
],
static_libs: [
+ "framework-connectivity-protos",
"modules-utils-build",
"modules-utils-preconditions",
],
libs: [
- "framework-connectivity-tiramisu.stubs.module_lib",
+ "framework-connectivity-t.stubs.module_lib",
"unsupportedappusage",
],
apex_available: [
@@ -177,3 +179,23 @@
"com.android.tethering",
],
}
+
+// TODO: reduce size of this library; consider using
+// proto nano for example
+java_library {
+ name: "framework-connectivity-protos",
+ sdk_version: "module_current",
+ min_sdk_version: "30",
+ proto: {
+ type: "lite",
+ },
+ srcs: [
+ "proto/**/*.*",
+ ],
+ static_libs: ["libprotobuf-java-lite"],
+ apex_available: [
+ "com.android.tethering",
+ ],
+ lint: { strict_updatability_linting: true },
+ visibility: ["//visibility:private"],
+}
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index 5579db6..713d35a 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -92,7 +92,7 @@
method public static void setDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
method public static void setDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, @IntRange(from=0, to=100) int);
method public static void setGlobalProxy(@NonNull android.content.Context, @NonNull android.net.ProxyInfo);
- method public static void setIngressRateLimitInBytesPerSecond(@NonNull android.content.Context, @IntRange(from=0xffffffff, to=java.lang.Integer.MAX_VALUE) long);
+ method public static void setIngressRateLimitInBytesPerSecond(@NonNull android.content.Context, @IntRange(from=-1L, to=4294967295L) long);
method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
method public static void setMobileDataPreferredUids(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
diff --git a/framework/proto/netstats.proto b/framework/proto/netstats.proto
new file mode 100644
index 0000000..3c9f73c
--- /dev/null
+++ b/framework/proto/netstats.proto
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.service;
+
+option java_multiple_files = true;
+option java_outer_classname = "NetworkStatsServiceProto";
+
+// Represents dumpsys from NetworkStatsService (netstats).
+message NetworkStatsServiceDumpProto {
+ repeated NetworkInterfaceProto active_interfaces = 1;
+
+ repeated NetworkInterfaceProto active_uid_interfaces = 2;
+
+ // Device level network stats, which may include non-IP layer traffic.
+ optional NetworkStatsRecorderProto dev_stats = 3;
+
+ // IP-layer traffic stats.
+ optional NetworkStatsRecorderProto xt_stats = 4;
+
+ // Per-UID network stats.
+ optional NetworkStatsRecorderProto uid_stats = 5;
+
+ // Per-UID, per-tag network stats, excluding the default tag (i.e. tag=0).
+ optional NetworkStatsRecorderProto uid_tag_stats = 6;
+}
+
+// Corresponds to NetworkStatsService.mActiveIfaces/mActiveUidIfaces.
+message NetworkInterfaceProto {
+ // Name of the network interface (eg: wlan).
+ optional string interface = 1;
+
+ optional NetworkIdentitySetProto identities = 2;
+}
+
+// Corresponds to NetworkIdentitySet.
+message NetworkIdentitySetProto {
+ repeated NetworkIdentityProto identities = 1;
+}
+
+// Corresponds to NetworkIdentity.
+message NetworkIdentityProto {
+ // Constants from ConnectivityManager.TYPE_*.
+ optional int32 type = 1;
+
+ optional bool roaming = 4;
+
+ optional bool metered = 5;
+
+ optional bool default_network = 6;
+
+ optional int32 oem_managed_network = 7;
+}
+
+// Corresponds to NetworkStatsRecorder.
+message NetworkStatsRecorderProto {
+ optional int64 pending_total_bytes = 1;
+
+ optional NetworkStatsCollectionProto complete_history = 2;
+}
+
+// Corresponds to NetworkStatsCollection.
+message NetworkStatsCollectionProto {
+ repeated NetworkStatsCollectionStatsProto stats = 1;
+}
+
+// Corresponds to NetworkStatsCollection.mStats.
+message NetworkStatsCollectionStatsProto {
+ optional NetworkStatsCollectionKeyProto key = 1;
+
+ optional NetworkStatsHistoryProto history = 2;
+}
+
+// Corresponds to NetworkStatsCollection.Key.
+message NetworkStatsCollectionKeyProto {
+ optional NetworkIdentitySetProto identity = 1;
+
+ optional int32 uid = 2;
+
+ optional int32 set = 3;
+
+ optional int32 tag = 4;
+}
+
+// Corresponds to NetworkStatsHistory.
+message NetworkStatsHistoryProto {
+ // Duration for this bucket in milliseconds.
+ optional int64 bucket_duration_ms = 1;
+
+ repeated NetworkStatsHistoryBucketProto buckets = 2;
+}
+
+// Corresponds to each bucket in NetworkStatsHistory.
+message NetworkStatsHistoryBucketProto {
+ // Bucket start time in milliseconds since epoch.
+ optional int64 bucket_start_ms = 1;
+
+ optional int64 rx_bytes = 2;
+
+ optional int64 rx_packets = 3;
+
+ optional int64 tx_bytes = 4;
+
+ optional int64 tx_packets = 5;
+
+ optional int64 operations = 6;
+}
\ No newline at end of file
diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java
index 4e28b29..822e67d 100644
--- a/framework/src/android/net/ConnectivitySettingsManager.java
+++ b/framework/src/android/net/ConnectivitySettingsManager.java
@@ -1081,10 +1081,10 @@
}
/**
- * Get the global network bandwidth rate limit.
+ * Get the network bandwidth ingress rate limit.
*
- * The limit is only applicable to networks that provide internet connectivity. If the setting
- * is unset, it defaults to -1.
+ * The limit is only applicable to networks that provide internet connectivity. -1 codes for no
+ * bandwidth limitation.
*
* @param context The {@link Context} to query the setting.
* @return The rate limit in number of bytes per second or -1 if disabled.
@@ -1095,15 +1095,17 @@
}
/**
- * Set the global network bandwidth rate limit.
+ * Set the network bandwidth ingress rate limit.
*
- * The limit is only applicable to networks that provide internet connectivity.
+ * The limit is applied to all networks that provide internet connectivity. It is applied on a
+ * per-network basis, meaning that global ingress rate could exceed the limit when communicating
+ * on multiple networks simultaneously.
*
* @param context The {@link Context} to set the setting.
* @param rateLimitInBytesPerSec The rate limit in number of bytes per second or -1 to disable.
*/
public static void setIngressRateLimitInBytesPerSecond(@NonNull Context context,
- @IntRange(from = -1, to = Integer.MAX_VALUE) long rateLimitInBytesPerSec) {
+ @IntRange(from = -1L, to = 0xFFFFFFFFL) long rateLimitInBytesPerSec) {
if (rateLimitInBytesPerSec < -1) {
throw new IllegalArgumentException(
"Rate limit must be within the range [-1, Integer.MAX_VALUE]");
diff --git a/nearby/Android.bp b/nearby/Android.bp
deleted file mode 100644
index baa0740..0000000
--- a/nearby/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- // See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-// Empty sources and libraries to avoid merge conflicts with downstream
-// branches
-// TODO: remove once the Nearby sources are available in this branch
-filegroup {
- name: "framework-nearby-java-sources",
- srcs: [],
- visibility: ["//packages/modules/Connectivity:__subpackages__"],
-}
-
-
-java_library {
- name: "service-nearby",
- srcs: [],
- sdk_version: "module_current",
- min_sdk_version: "30",
- apex_available: ["com.android.tethering"],
- visibility: ["//packages/modules/Connectivity:__subpackages__"],
-}
diff --git a/service-t/Android.bp b/service-t/Android.bp
index 8ba0768..3d9820d 100644
--- a/service-t/Android.bp
+++ b/service-t/Android.bp
@@ -19,10 +19,10 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-// This builds T+ services depending on framework-connectivity-tiramisu
+// This builds T+ services depending on framework-connectivity-t
// hidden symbols separately from the S+ services, to ensure that S+
// services cannot accidentally depend on T+ hidden symbols from
-// framework-connectivity-tiramisu.
+// framework-connectivity-t.
java_library {
name: "service-connectivity-tiramisu-pre-jarjar",
sdk_version: "system_server_current",
@@ -30,16 +30,15 @@
min_sdk_version: "30",
srcs: [
"src/**/*.java",
- // TODO: This is necessary just for LocalLog, remove after removing NativeDaemonConnector.
- ":framework-connectivity-shared-srcs",
":services.connectivity-tiramisu-updatable-sources",
],
libs: [
"framework-annotations-lib",
"framework-connectivity-pre-jarjar",
- "framework-connectivity-tiramisu-pre-jarjar",
+ "framework-connectivity-t-pre-jarjar",
"framework-tethering.stubs.module_lib",
"service-connectivity-pre-jarjar",
+ "service-nearby",
"unsupportedappusage",
],
static_libs: [
diff --git a/service-t/native/libs/libnetworkstats/Android.bp b/service-t/native/libs/libnetworkstats/Android.bp
index d24b14b..bf56fd5 100644
--- a/service-t/native/libs/libnetworkstats/Android.bp
+++ b/service-t/native/libs/libnetworkstats/Android.bp
@@ -41,7 +41,6 @@
cfi: true,
},
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
min_sdk_version: "30",
diff --git a/service-t/src/com/android/server/ConnectivityServiceInitializer.java b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
index 67757af..d11f0f2 100644
--- a/service-t/src/com/android/server/ConnectivityServiceInitializer.java
+++ b/service-t/src/com/android/server/ConnectivityServiceInitializer.java
@@ -20,16 +20,18 @@
import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
+import com.android.server.nearby.NearbyService;
/**
* Connectivity service initializer for core networking. This is called by system server to create
- * a new instance of ConnectivityService.
+ * a new instance of connectivity services.
*/
public final class ConnectivityServiceInitializer extends SystemService {
private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName();
private final ConnectivityService mConnectivity;
private final IpSecService mIpSecService;
private final NsdService mNsdService;
+ private final NearbyService mNearbyService;
public ConnectivityServiceInitializer(Context context) {
super(context);
@@ -38,6 +40,7 @@
mConnectivity = new ConnectivityService(context);
mIpSecService = createIpSecService(context);
mNsdService = createNsdService(context);
+ mNearbyService = createNearbyService(context);
}
@Override
@@ -55,6 +58,19 @@
Log.i(TAG, "Registering " + Context.NSD_SERVICE);
publishBinderService(Context.NSD_SERVICE, mNsdService, /* allowIsolated= */ false);
}
+
+ if (mNearbyService != null) {
+ Log.i(TAG, "Registering " + Context.NEARBY_SERVICE);
+ publishBinderService(Context.NEARBY_SERVICE, mNearbyService,
+ /* allowIsolated= */ false);
+ }
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (mNearbyService != null) {
+ mNearbyService.onBootPhase(phase);
+ }
}
/**
@@ -76,4 +92,10 @@
return null;
}
}
+
+ /** Return Nearby service instance or null if current SDK is lower than T */
+ private NearbyService createNearbyService(final Context context) {
+ if (!SdkLevel.isAtLeastT()) return null;
+ return new NearbyService(context);
+ }
}
diff --git a/service-t/src/com/android/server/NetworkStatsServiceInitializer.java b/service-t/src/com/android/server/NetworkStatsServiceInitializer.java
new file mode 100644
index 0000000..0ea126a
--- /dev/null
+++ b/service-t/src/com/android/server/NetworkStatsServiceInitializer.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.net.TrafficStats;
+import android.util.Log;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.server.net.NetworkStatsService;
+
+/**
+ * NetworkStats service initializer for core networking. This is called by system server to create
+ * a new instance of NetworkStatsService.
+ */
+public final class NetworkStatsServiceInitializer extends SystemService {
+ private static final String TAG = NetworkStatsServiceInitializer.class.getSimpleName();
+ private final NetworkStatsService mStatsService;
+
+ public NetworkStatsServiceInitializer(Context context) {
+ super(context);
+ // Load JNI libraries used by NetworkStatsService and its dependencies
+ System.loadLibrary("service-connectivity");
+ mStatsService = maybeCreateNetworkStatsService(context);
+ }
+
+ @Override
+ public void onStart() {
+ if (mStatsService != null) {
+ Log.i(TAG, "Registering " + Context.NETWORK_STATS_SERVICE);
+ publishBinderService(Context.NETWORK_STATS_SERVICE, mStatsService,
+ /* allowIsolated= */ false);
+ TrafficStats.init(getContext());
+ }
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ // This has to be run before StatsPullAtomService query usage at
+ // PHASE_THIRD_PARTY_APPS_CAN_START.
+ if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY && mStatsService != null) {
+ mStatsService.systemReady();
+ }
+ }
+
+ /**
+ * Return NetworkStatsService instance, or null if current SDK is lower than T.
+ */
+ private NetworkStatsService maybeCreateNetworkStatsService(final Context context) {
+ if (!SdkLevel.isAtLeastT()) return null;
+
+ return NetworkStatsService.create(context);
+ }
+}
diff --git a/service/Android.bp b/service/Android.bp
index d600231..3e9ef1a 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -55,6 +55,7 @@
"-Wthread-safety",
],
srcs: [
+ ":services.connectivity-netstats-jni-sources",
"jni/com_android_server_BpfNetMaps.cpp",
"jni/com_android_server_connectivity_ClatCoordinator.cpp",
"jni/com_android_server_TestNetworkService.cpp",
@@ -66,15 +67,19 @@
static_libs: [
"libclat",
"libip_checksum",
+ "libmodules-utils-build",
"libnetjniutils",
+ "libnet_utils_device_common_bpfjni",
"libtraffic_controller",
"netd_aidl_interface-lateststable-ndk",
],
shared_libs: [
"libbase",
+ "libcutils",
"libnetdutils",
"liblog",
"libnativehelper",
+ "libnetworkstats",
],
apex_available: [
"com.android.tethering",
@@ -95,6 +100,7 @@
libs: [
"framework-annotations-lib",
"framework-connectivity-pre-jarjar",
+ "framework-connectivity-t.stubs.module_lib",
"framework-tethering.stubs.module_lib",
"framework-wifi.stubs.module_lib",
"unsupportedappusage",
@@ -112,7 +118,7 @@
"networkstack-client",
"PlatformProperties",
"service-connectivity-protos",
- "NetworkStackApiStableShims",
+ "NetworkStackApiCurrentShims",
],
apex_available: [
"com.android.tethering",
@@ -159,6 +165,11 @@
apex_available: [
"com.android.tethering",
],
+ optimize: {
+ enabled: true,
+ shrink: true,
+ proguard_flags_files: ["proguard.flags"],
+ },
lint: { strict_updatability_linting: true },
}
diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt
index e3b26fd..ee05df5 100644
--- a/service/jarjar-rules.txt
+++ b/service/jarjar-rules.txt
@@ -9,19 +9,22 @@
# From modules-utils-preconditions
rule com.android.internal.util.Preconditions* android.net.connectivity.@0
+# From framework-connectivity-shared-srcs
+rule android.util.LocalLog* android.net.connectivity.@0
+rule android.util.IndentingPrintWriter* android.net.connectivity.@0
+rule com.android.internal.util.IndentingPrintWriter* android.net.connectivity.@0
+rule com.android.internal.util.MessageUtils* android.net.connectivity.@0
+rule com.android.internal.util.WakeupMessage* android.net.connectivity.@0
+rule com.android.internal.util.FileRotator* android.net.connectivity.@0
+rule com.android.internal.util.ProcFileReader* android.net.connectivity.@0
+
+# From framework-connectivity-protos
+rule com.google.protobuf.** android.net.connectivity.@0
+rule android.service.** android.net.connectivity.@0
+
rule android.sysprop.** com.android.connectivity.@0
-# internal util classes from framework-connectivity-shared-srcs
-rule android.util.LocalLog* com.android.connectivity.@0
-# android.util.IndentingPrintWriter* should use a different package name from
-# the one in com.android.internal.util
-rule android.util.IndentingPrintWriter* com.android.connectivity.@0
-rule com.android.internal.util.IndentingPrintWriter* com.android.connectivity.@0
-rule com.android.internal.util.MessageUtils* com.android.connectivity.@0
-rule com.android.internal.util.WakeupMessage* com.android.connectivity.@0
-
rule com.android.internal.messages.** com.android.connectivity.@0
-rule com.google.protobuf.** com.android.connectivity.@0
# From dnsresolver_aidl_interface (newer AIDLs should go to android.net.resolv.aidl)
rule android.net.resolv.aidl.** com.android.connectivity.@0
@@ -103,5 +106,8 @@
# From the API shims
rule com.android.networkstack.apishim.** com.android.connectivity.@0
+# From fast-pair-lite-protos
+rule service.proto.** com.android.server.nearby.@0
+
# Remaining are connectivity sources in com.android.server and com.android.server.connectivity:
# TODO: move to a subpackage of com.android.connectivity (such as com.android.connectivity.server)
diff --git a/service/jni/com_android_server_BpfNetMaps.cpp b/service/jni/com_android_server_BpfNetMaps.cpp
index 85cfc09..f13c68d 100644
--- a/service/jni/com_android_server_BpfNetMaps.cpp
+++ b/service/jni/com_android_server_BpfNetMaps.cpp
@@ -24,6 +24,7 @@
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedUtfChars.h>
#include <nativehelper/ScopedPrimitiveArray.h>
+#include <netjniutils/netjniutils.h>
#include <net/if.h>
#include <vector>
@@ -108,6 +109,7 @@
}
size_t size = uids.size();
+ static_assert(sizeof(*(uids.get())) == sizeof(int32_t));
std::vector<int32_t> data ((int32_t *)&uids[0], (int32_t*)&uids[size]);
int res = mTc.replaceUidOwnerMap(chainName, isAllowlist, data);
if (res) {
@@ -144,6 +146,7 @@
}
size_t size = uids.size();
+ static_assert(sizeof(*(uids.get())) == sizeof(int32_t));
std::vector<int32_t> data ((int32_t *)&uids[0], (int32_t*)&uids[size]);
Status status = mTc.addUidInterfaceRules(ifIndex, data);
if (!isOk(status)) {
@@ -159,6 +162,7 @@
}
size_t size = uids.size();
+ static_assert(sizeof(*(uids.get())) == sizeof(int32_t));
std::vector<int32_t> data ((int32_t *)&uids[0], (int32_t*)&uids[size]);
Status status = mTc.removeUidInterfaceRules(data);
if (!isOk(status)) {
@@ -186,6 +190,15 @@
mTc.setPermissionForUids(permission, data);
}
+static void native_dump(JNIEnv* env, jobject clazz, jobject javaFd, jboolean verbose) {
+ int fd = netjniutils::GetNativeFileDescriptor(env, javaFd);
+ if (fd < 0) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
+ return;
+ }
+ mTc.dump(fd, verbose);
+}
+
/*
* JNI registration.
*/
@@ -216,6 +229,8 @@
(void*)native_swapActiveStatsMap},
{"native_setPermissionForUids", "(I[I)V",
(void*)native_setPermissionForUids},
+ {"native_dump", "(Ljava/io/FileDescriptor;Z)V",
+ (void*)native_dump},
};
// clang-format on
diff --git a/service/jni/onload.cpp b/service/jni/onload.cpp
index facdad7..3d15d43 100644
--- a/service/jni/onload.cpp
+++ b/service/jni/onload.cpp
@@ -17,11 +17,15 @@
#include <nativehelper/JNIHelp.h>
#include <log/log.h>
+#include <android-modules-utils/sdk_level.h>
+
namespace android {
int register_com_android_server_TestNetworkService(JNIEnv* env);
int register_com_android_server_connectivity_ClatCoordinator(JNIEnv* env);
int register_com_android_server_BpfNetMaps(JNIEnv* env);
+int register_android_server_net_NetworkStatsFactory(JNIEnv* env);
+int register_android_server_net_NetworkStatsService(JNIEnv* env);
extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv *env;
@@ -42,6 +46,16 @@
return JNI_ERR;
}
+ if (android::modules::sdklevel::IsAtLeastT()) {
+ if (register_android_server_net_NetworkStatsFactory(env) < 0) {
+ return JNI_ERR;
+ }
+
+ if (register_android_server_net_NetworkStatsService(env) < 0) {
+ return JNI_ERR;
+ }
+ }
+
return JNI_VERSION_1_6;
}
diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp
index 1cbfd94..3e98edb 100644
--- a/service/native/TrafficController.cpp
+++ b/service/native/TrafficController.cpp
@@ -65,7 +65,6 @@
using netdutils::Status;
using netdutils::statusFromErrno;
using netdutils::StatusOr;
-using netdutils::status::ok;
constexpr int kSockDiagMsgType = SOCK_DIAG_BY_FAMILY;
constexpr int kSockDiagDoneMsgType = NLMSG_DONE;
@@ -601,8 +600,10 @@
}
}
-void TrafficController::dump(DumpWriter& dw, bool verbose) {
+void TrafficController::dump(int fd, bool verbose) {
std::lock_guard guard(mMutex);
+ DumpWriter dw(fd);
+
ScopedIndent indentTop(dw);
dw.println("TrafficController");
diff --git a/service/native/include/TrafficController.h b/service/native/include/TrafficController.h
index 6fe117f..79e75ac 100644
--- a/service/native/include/TrafficController.h
+++ b/service/native/include/TrafficController.h
@@ -62,7 +62,7 @@
netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
FirewallType type) EXCLUDES(mMutex);
- void dump(netdutils::DumpWriter& dw, bool verbose) EXCLUDES(mMutex);
+ void dump(int fd, bool verbose) EXCLUDES(mMutex);
netdutils::Status replaceRulesInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids)
EXCLUDES(mMutex);
diff --git a/service/native/libs/libclat/bpfhelper.cpp b/service/native/libs/libclat/bpfhelper.cpp
index 6e230d0..00785ad 100644
--- a/service/native/libs/libclat/bpfhelper.cpp
+++ b/service/native/libs/libclat/bpfhelper.cpp
@@ -28,16 +28,6 @@
#define DEVICEPREFIX "v4-"
using android::base::unique_fd;
-using android::net::RAWIP;
-using android::net::getClatEgress4MapFd;
-using android::net::getClatIngress6MapFd;
-using android::net::getClatEgress4ProgFd;
-using android::net::getClatIngress6ProgFd;
-using android::net::tcQdiscAddDevClsact;
-using android::net::tcFilterAddDevEgressClatIpv4;
-using android::net::tcFilterAddDevIngressClatIpv6;
-using android::net::tcFilterDelDevEgressClatIpv4;
-using android::net::tcFilterDelDevIngressClatIpv6;
using android::bpf::BpfMap;
BpfMap<ClatEgress4Key, ClatEgress4Value> mClatEgress4Map;
diff --git a/service/proguard.flags b/service/proguard.flags
new file mode 100644
index 0000000..2b20ddd
--- /dev/null
+++ b/service/proguard.flags
@@ -0,0 +1,21 @@
+# Make sure proguard keeps all connectivity classes
+# TODO: instead of keeping everything, consider listing only "entry points"
+# (service loader, JNI registered methods, etc) and letting the optimizer do its job
+-keep class android.net.** { *; }
+-keep class com.android.connectivity.** { *; }
+-keep class com.android.net.** { *; }
+-keep class com.android.server.** { *; }
+
+# Prevent proguard from stripping out any nearby-service and fast-pair-lite-protos fields.
+# TODO: This could be optimized in the future to only keep the critical
+# entry points and then let proguard strip out any unused code within
+# the service. "com.android.server.nearby.service.proto" must be kept to prevent proguard
+# from stripping out any fast-pair-lite-protos fields.
+-keep class com.android.server.nearby.** { *; }
+
+# The lite proto runtime uses reflection to access fields based on the names in
+# the schema, keep all the fields.
+# This replicates the base proguard rule used by the build by default
+# (proguard_basic_keeps.flags), but needs to be specified here because the
+# com.google.protobuf package is jarjared to the below package.
+-keepclassmembers class * extends com.android.connectivity.com.google.protobuf.MessageLite { <fields>; }
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index ddee275..f2ca18b 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.system.OsConstants.EOPNOTSUPP;
+
import android.net.INetd;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -24,6 +26,9 @@
import com.android.modules.utils.build.SdkLevel;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
/**
* BpfNetMaps is responsible for providing traffic controller relevant functionality.
*
@@ -273,6 +278,23 @@
native_setPermissionForUids(permissions, uids);
}
+ /**
+ * Dump BPF maps
+ *
+ * @param fd file descriptor to output
+ * @throws IOException when file descriptor is invalid.
+ * @throws ServiceSpecificException when the method is called on an unsupported device.
+ */
+ public void dump(final FileDescriptor fd, boolean verbose)
+ throws IOException, ServiceSpecificException {
+ if (USE_NETD) {
+ throw new ServiceSpecificException(
+ EOPNOTSUPP, "dumpsys connectivity trafficcontroller dump not available on pre-T"
+ + " devices, use dumpsys netd trafficcontroller instead.");
+ }
+ native_dump(fd, verbose);
+ }
+
private static native void native_init();
private native int native_addNaughtyApp(int uid);
private native int native_removeNaughtyApp(int uid);
@@ -285,4 +307,5 @@
private native int native_removeUidInterfaceRules(int[] uids);
private native int native_swapActiveStatsMap();
private native void native_setPermissionForUids(int permissions, int[] uids);
+ private native void native_dump(FileDescriptor fd, boolean verbose);
}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 6024a2a..c90fcd5 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -313,6 +313,7 @@
public static final String SHORT_ARG = "--short";
private static final String NETWORK_ARG = "networks";
private static final String REQUEST_ARG = "requests";
+ private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller";
private static final boolean DBG = true;
private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
@@ -645,8 +646,9 @@
* Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
* Both of the arguments are bitmasks, and the value of bits come from
* INetworkMonitor.NETWORK_VALIDATION_PROBE_*.
- * arg1 = A bitmask to describe which probes are completed.
- * arg2 = A bitmask to describe which probes are successful.
+ * arg1 = unused
+ * arg2 = netId
+ * obj = A Pair of integers: the bitmasks of, respectively, completed and successful probes.
*/
public static final int EVENT_PROBE_STATUS_CHANGED = 45;
@@ -1409,6 +1411,8 @@
// converting rateInBytesPerSecond from long to int is safe here because the
// setting's range is limited to INT_MAX.
// TODO: add long/uint64 support to tcFilterAddDevIngressPolice.
+ Log.i(TAG,
+ "enableIngressRateLimit on " + iface + ": " + rateInBytesPerSecond + "B/s");
TcUtils.tcFilterAddDevIngressPolice(params.index, TC_PRIO_POLICE, (short) ETH_P_ALL,
(int) rateInBytesPerSecond, TC_POLICE_BPF_PROG_PATH);
} catch (IOException e) {
@@ -1430,6 +1434,8 @@
return;
}
try {
+ Log.i(TAG,
+ "disableIngressRateLimit on " + iface);
TcUtils.tcFilterDelDev(params.index, true, TC_PRIO_POLICE, (short) ETH_P_ALL);
} catch (IOException e) {
loge("TcUtils.tcFilterDelDev(ifaceIndex=" + params.index
@@ -1752,7 +1758,7 @@
// Watch for ingress rate limit changes.
mSettingsObserver.observe(
- Settings.Secure.getUriFor(
+ Settings.Global.getUriFor(
ConnectivitySettingsManager.INGRESS_RATE_LIMIT_BYTES_PER_SECOND),
EVENT_INGRESS_RATE_LIMIT_CHANGED);
}
@@ -3212,6 +3218,10 @@
} else if (CollectionUtils.contains(args, REQUEST_ARG)) {
dumpNetworkRequests(pw);
return;
+ } else if (CollectionUtils.contains(args, TRAFFICCONTROLLER_ARG)) {
+ boolean verbose = !CollectionUtils.contains(args, SHORT_ARG);
+ dumpTrafficController(pw, fd, verbose);
+ return;
}
pw.print("NetworkProviders for:");
@@ -3429,6 +3439,17 @@
}
}
+ private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd,
+ boolean verbose) {
+ try {
+ mBpfNetMaps.dump(fd, verbose);
+ } catch (ServiceSpecificException e) {
+ pw.println(e.getMessage());
+ } catch (IOException e) {
+ loge("Dump BPF maps failed, " + e);
+ }
+ }
+
private void dumpAllRequestInfoLogsToLogcat() {
try (PrintWriter logPw = new PrintWriter(new Writer() {
@Override
@@ -3602,19 +3623,21 @@
}
private boolean maybeHandleNetworkMonitorMessage(Message msg) {
+ final int netId = msg.arg2;
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
switch (msg.what) {
default:
return false;
case EVENT_PROBE_STATUS_CHANGED: {
- final Integer netId = (Integer) msg.obj;
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
if (nai == null) {
break;
}
+ final int probesCompleted = ((Pair<Integer, Integer>) msg.obj).first;
+ final int probesSucceeded = ((Pair<Integer, Integer>) msg.obj).second;
final boolean probePrivateDnsCompleted =
- ((msg.arg1 & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
+ ((probesCompleted & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
final boolean privateDnsBroken =
- ((msg.arg2 & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
+ ((probesSucceeded & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
if (probePrivateDnsCompleted) {
if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) {
nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken);
@@ -3641,7 +3664,6 @@
case EVENT_NETWORK_TESTED: {
final NetworkTestedResults results = (NetworkTestedResults) msg.obj;
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(results.mNetId);
if (nai == null) break;
handleNetworkTested(nai, results.mTestResult,
@@ -3649,9 +3671,7 @@
break;
}
case EVENT_PROVISIONING_NOTIFICATION: {
- final int netId = msg.arg2;
final boolean visible = toBool(msg.arg1);
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
// If captive portal status has changed, update capabilities or disconnect.
if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
nai.lastCaptivePortalDetected = visible;
@@ -3685,14 +3705,12 @@
break;
}
case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
if (nai == null) break;
updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
break;
}
case EVENT_CAPPORT_DATA_CHANGED: {
- final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
if (nai == null) break;
handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
break;
@@ -3832,6 +3850,7 @@
// the same looper so messages will be processed in sequence.
final Message msg = mTrackerHandler.obtainMessage(
EVENT_NETWORK_TESTED,
+ 0, mNetId,
new NetworkTestedResults(
mNetId, p.result, p.timestampMillis, p.redirectUrl));
mTrackerHandler.sendMessage(msg);
@@ -3854,7 +3873,7 @@
ConnectivityReportEvent reportEvent =
new ConnectivityReportEvent(p.timestampMillis, nai, extras);
final Message m = mConnectivityDiagnosticsHandler.obtainMessage(
- ConnectivityDiagnosticsHandler.EVENT_NETWORK_TESTED, reportEvent);
+ ConnectivityDiagnosticsHandler.CMD_SEND_CONNECTIVITY_REPORT, reportEvent);
mConnectivityDiagnosticsHandler.sendMessage(m);
}
@@ -3869,7 +3888,7 @@
public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) {
mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
EVENT_PROBE_STATUS_CHANGED,
- probesCompleted, probesSucceeded, new Integer(mNetId)));
+ 0, mNetId, new Pair<>(probesCompleted, probesSucceeded)));
}
@Override
@@ -9579,14 +9598,12 @@
/**
* Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks
- * after processing {@link #EVENT_NETWORK_TESTED} events.
+ * after processing {@link #CMD_SEND_CONNECTIVITY_REPORT} events.
* obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from
* NetworkMonitor.
* data = PersistableBundle of extras passed from NetworkMonitor.
- *
- * <p>See {@link ConnectivityService#EVENT_NETWORK_TESTED}.
*/
- private static final int EVENT_NETWORK_TESTED = ConnectivityService.EVENT_NETWORK_TESTED;
+ private static final int CMD_SEND_CONNECTIVITY_REPORT = 3;
/**
* Event for NetworkMonitor to inform ConnectivityService that a potential data stall has
@@ -9624,7 +9641,7 @@
(IConnectivityDiagnosticsCallback) msg.obj, msg.arg1);
break;
}
- case EVENT_NETWORK_TESTED: {
+ case CMD_SEND_CONNECTIVITY_REPORT: {
final ConnectivityReportEvent reportEvent =
(ConnectivityReportEvent) msg.obj;
@@ -10684,15 +10701,19 @@
}
private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) {
- if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)) {
- // rate limits only apply to networks that provide internet connectivity.
+ final NetworkCapabilities agentCaps = networkAgent.networkCapabilities;
+ // Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide
+ // internet connectivity can be rate limited.
+ if (!agentCaps.hasCapability(NET_CAPABILITY_INTERNET) && !agentCaps.hasTransport(
+ TRANSPORT_TEST)) {
return false;
}
final String iface = networkAgent.linkProperties.getInterfaceName();
if (iface == null) {
- // This can never happen.
- logwtf("canNetworkBeRateLimited: LinkProperties#getInterfaceName returns null");
+ // This may happen in tests, but if there is no interface then there is nothing that
+ // can be rate limited.
+ loge("canNetworkBeRateLimited: LinkProperties#getInterfaceName returns null");
return false;
}
return true;
diff --git a/service/src/com/android/server/connectivity/FullScore.java b/service/src/com/android/server/connectivity/FullScore.java
index aebb80d..799f46b 100644
--- a/service/src/com/android/server/connectivity/FullScore.java
+++ b/service/src/com/android/server/connectivity/FullScore.java
@@ -21,8 +21,6 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkScore.KEEP_CONNECTED_NONE;
-import static android.net.NetworkScore.POLICY_EXITING;
-import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY;
import static android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI;
import android.annotation.IntDef;
@@ -31,8 +29,10 @@
import android.net.NetworkCapabilities;
import android.net.NetworkScore;
import android.net.NetworkScore.KeepConnectedReason;
+import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.MessageUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -98,9 +98,17 @@
/** @hide */
public static final int POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD = 57;
+ // The network agent has communicated that this network no longer functions, and the underlying
+ // native network has been destroyed. The network will still be reported to clients as connected
+ // until a timeout expires, the agent disconnects, or the network no longer satisfies requests.
+ // This network should lose to an identical network that has not been destroyed, but should
+ // otherwise be scored exactly the same.
+ /** @hide */
+ public static final int POLICY_IS_DESTROYED = 56;
+
// To help iterate when printing
@VisibleForTesting
- static final int MIN_CS_MANAGED_POLICY = POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD;
+ static final int MIN_CS_MANAGED_POLICY = POLICY_IS_DESTROYED;
@VisibleForTesting
static final int MAX_CS_MANAGED_POLICY = POLICY_IS_VALIDATED;
@@ -112,21 +120,14 @@
private static final long EXTERNAL_POLICIES_MASK =
0x00000000FFFFFFFFL & ~(1L << POLICY_YIELD_TO_BAD_WIFI);
+ private static SparseArray<String> sMessageNames = MessageUtils.findMessageNames(
+ new Class[]{FullScore.class, NetworkScore.class}, new String[]{"POLICY_"});
+
@VisibleForTesting
static @NonNull String policyNameOf(final int policy) {
- switch (policy) {
- case POLICY_IS_VALIDATED: return "IS_VALIDATED";
- case POLICY_IS_VPN: return "IS_VPN";
- case POLICY_EVER_USER_SELECTED: return "EVER_USER_SELECTED";
- case POLICY_ACCEPT_UNVALIDATED: return "ACCEPT_UNVALIDATED";
- case POLICY_IS_UNMETERED: return "IS_UNMETERED";
- case POLICY_YIELD_TO_BAD_WIFI: return "YIELD_TO_BAD_WIFI";
- case POLICY_TRANSPORT_PRIMARY: return "TRANSPORT_PRIMARY";
- case POLICY_EXITING: return "EXITING";
- case POLICY_IS_INVINCIBLE: return "INVINCIBLE";
- case POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD: return "EVER_VALIDATED";
- }
- throw new IllegalArgumentException("Unknown policy : " + policy);
+ final String name = sMessageNames.get(policy);
+ if (name == null) throw new IllegalArgumentException("Unknown policy: " + policy);
+ return name.substring("POLICY_".length());
}
// Bitmask of all the policies applied to this score.
@@ -149,6 +150,7 @@
* @param config the NetworkAgentConfig of the network
* @param everValidated whether this network has ever validated
* @param yieldToBadWiFi whether this network yields to a previously validated wifi gone bad
+ * @param destroyed whether this network has been destroyed pending a replacement connecting
* @return a FullScore that is appropriate to use for ranking.
*/
// TODO : this shouldn't manage bad wifi avoidance – instead this should be done by the
@@ -156,7 +158,7 @@
// connectivity for backward compatibility.
public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
@NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config,
- final boolean everValidated, final boolean yieldToBadWiFi) {
+ final boolean everValidated, final boolean yieldToBadWiFi, final boolean destroyed) {
return withPolicies(score.getLegacyInt(), score.getPolicies(),
score.getKeepConnectedReason(),
caps.hasCapability(NET_CAPABILITY_VALIDATED),
@@ -166,6 +168,7 @@
config.explicitlySelected,
config.acceptUnvalidated,
yieldToBadWiFi,
+ destroyed,
false /* invincible */); // only prospective scores can be invincible
}
@@ -174,7 +177,7 @@
*
* NetworkOffers have score filters that are compared to the scores of actual networks
* to see if they could possibly beat the current satisfier. Some things the agent can't
- * know in advance ; a good example is the validation bit – some networks will validate,
+ * know in advance; a good example is the validation bit – some networks will validate,
* others won't. For comparison purposes, assume the best, so all possibly beneficial
* networks will be brought up.
*
@@ -197,12 +200,14 @@
final boolean everUserSelected = false;
// Don't assume the user will accept unvalidated connectivity.
final boolean acceptUnvalidated = false;
+ // A network can only be destroyed once it has connected.
+ final boolean destroyed = false;
// A prospective score is invincible if the legacy int in the filter is over the maximum
// score.
final boolean invincible = score.getLegacyInt() > NetworkRanker.LEGACY_INT_MAX;
return withPolicies(score.getLegacyInt(), score.getPolicies(), KEEP_CONNECTED_NONE,
mayValidate, vpn, unmetered, everValidated, everUserSelected, acceptUnvalidated,
- yieldToBadWiFi, invincible);
+ yieldToBadWiFi, destroyed, invincible);
}
/**
@@ -218,7 +223,8 @@
public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
@NonNull final NetworkAgentConfig config,
final boolean everValidated,
- final boolean yieldToBadWifi) {
+ final boolean yieldToBadWifi,
+ final boolean destroyed) {
return withPolicies(mLegacyInt, mPolicies, mKeepConnectedReason,
caps.hasCapability(NET_CAPABILITY_VALIDATED),
caps.hasTransport(TRANSPORT_VPN),
@@ -227,6 +233,7 @@
config.explicitlySelected,
config.acceptUnvalidated,
yieldToBadWifi,
+ destroyed,
false /* invincible */); // only prospective scores can be invincible
}
@@ -243,6 +250,7 @@
final boolean everUserSelected,
final boolean acceptUnvalidated,
final boolean yieldToBadWiFi,
+ final boolean destroyed,
final boolean invincible) {
return new FullScore(legacyInt, (externalPolicies & EXTERNAL_POLICIES_MASK)
| (isValidated ? 1L << POLICY_IS_VALIDATED : 0)
@@ -252,6 +260,7 @@
| (everUserSelected ? 1L << POLICY_EVER_USER_SELECTED : 0)
| (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0)
| (yieldToBadWiFi ? 1L << POLICY_YIELD_TO_BAD_WIFI : 0)
+ | (destroyed ? 1L << POLICY_IS_DESTROYED : 0)
| (invincible ? 1L << POLICY_IS_INVINCIBLE : 0),
keepConnectedReason);
}
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index e917b3f..e29d616 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -106,6 +106,12 @@
// or tunnel) but does not disconnect from the AP/cell tower, or
// d. a stand-alone device offering a WiFi AP without an uplink for configuration purposes.
// 5. registered, created, connected, validated
+// 6. registered, created, connected, (validated or unvalidated), destroyed
+// This is an optional state where the underlying native network is destroyed but the network is
+// still connected for scoring purposes, so can satisfy requests, including the default request.
+// It is used when the transport layer wants to replace a network with another network (e.g.,
+// when Wi-Fi has roamed to a different BSSID that is part of a different L3 network) and does
+// not want the device to switch to another network until the replacement connects and validates.
//
// The device's default network connection:
// ----------------------------------------
@@ -184,6 +190,9 @@
// shows up in API calls, is able to satisfy NetworkRequests and can become the default network.
// This is a sticky bit; once set it is never cleared.
public boolean everConnected;
+ // Whether this network has been destroyed and is being kept temporarily until it is replaced.
+ public boolean destroyed;
+
// Set to true if this Network successfully passed validation or if it did not satisfy the
// default NetworkRequest in which case validation will not be attempted.
// This is a sticky bit; once set it is never cleared even if future validation attempts fail.
@@ -746,7 +755,7 @@
final NetworkCapabilities oldNc = networkCapabilities;
networkCapabilities = nc;
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidatedForYield(),
- yieldToBadWiFi());
+ yieldToBadWiFi(), destroyed);
final NetworkMonitorManager nm = mNetworkMonitor;
if (nm != null) {
nm.notifyNetworkCapabilitiesChanged(nc);
@@ -874,7 +883,7 @@
/**
* Returns the number of requests currently satisfied by this network of type
- * {@link android.net.NetworkRequest.Type.BACKGROUND_REQUEST}.
+ * {@link android.net.NetworkRequest.Type#BACKGROUND_REQUEST}.
*/
public int numBackgroundNetworkRequests() {
return mNumBackgroundNetworkRequests;
@@ -961,7 +970,7 @@
*/
public void setScore(final NetworkScore score) {
mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig,
- everValidatedForYield(), yieldToBadWiFi());
+ everValidatedForYield(), yieldToBadWiFi(), destroyed);
}
/**
@@ -971,7 +980,7 @@
*/
public void updateScoreForNetworkAgentUpdate() {
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig,
- everValidatedForYield(), yieldToBadWiFi());
+ everValidatedForYield(), yieldToBadWiFi(), destroyed);
}
private boolean everValidatedForYield() {
@@ -1019,7 +1028,7 @@
* when a network is newly created.
*
* @param requestId The requestId of the request that no longer need to be served by this
- * network. Or {@link NetworkRequest.REQUEST_ID_NONE} if this is the
+ * network. Or {@link NetworkRequest#REQUEST_ID_NONE} if this is the
* {@code InactivityTimer} for a newly created network.
*/
// TODO: Consider creating a dedicated function for nascent network, e.g. start/stopNascent.
diff --git a/service/src/com/android/server/connectivity/NetworkRanker.java b/service/src/com/android/server/connectivity/NetworkRanker.java
index 43da1d0..babc353 100644
--- a/service/src/com/android/server/connectivity/NetworkRanker.java
+++ b/service/src/com/android/server/connectivity/NetworkRanker.java
@@ -28,6 +28,7 @@
import static com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED;
import static com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED;
import static com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD;
+import static com.android.server.connectivity.FullScore.POLICY_IS_DESTROYED;
import static com.android.server.connectivity.FullScore.POLICY_IS_INVINCIBLE;
import static com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED;
import static com.android.server.connectivity.FullScore.POLICY_IS_VPN;
@@ -263,6 +264,15 @@
}
}
+ // If two networks are equivalent, and one has been destroyed pending replacement, keep the
+ // other one. This ensures that when the replacement connects, it's preferred.
+ partitionInto(candidates, nai -> !nai.getScore().hasPolicy(POLICY_IS_DESTROYED),
+ accepted, rejected);
+ if (accepted.size() == 1) return accepted.get(0);
+ if (accepted.size() > 0 && rejected.size() > 0) {
+ candidates = new ArrayList<>(accepted);
+ }
+
// At this point there are still multiple networks passing all the tests above. If any
// of them is the previous satisfier, keep it.
if (candidates.contains(currentSatisfier)) return currentSatisfier;
diff --git a/tests/TEST_MAPPING b/tests/TEST_MAPPING
deleted file mode 100644
index 502f885..0000000
--- a/tests/TEST_MAPPING
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "presubmit": [
- {
- "name": "FrameworksNetIntegrationTests"
- }
- ],
- "postsubmit": [
- {
- "name": "FrameworksNetDeflakeTest"
- }
- ],
- "auto-postsubmit": [
- // Test tag for automotive targets. These are only running in postsubmit so as to harden the
- // automotive targets to avoid introducing additional test flake and build time. The plan for
- // presubmit testing for auto is to augment the existing tests to cover auto use cases as well.
- // Additionally, this tag is used in targeted test suites to limit resource usage on the test
- // infra during the hardening phase.
- // TODO: this tag to be removed once the above is no longer an issue.
- {
- "name": "FrameworksNetTests"
- },
- {
- "name": "FrameworksNetIntegrationTests"
- },
- {
- "name": "FrameworksNetDeflakeTest"
- }
- ],
- "imports": [
- {
- "path": "packages/modules/Connectivity"
- }
- ]
-}
\ No newline at end of file
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
index 8782684..b23074d 100644
--- a/tests/common/Android.bp
+++ b/tests/common/Android.bp
@@ -115,7 +115,7 @@
// meaning @hide APIs in framework-connectivity are resolved before @SystemApi
// stubs in framework
"framework-connectivity.impl",
- "framework-connectivity-tiramisu.impl",
+ "framework-connectivity-t.impl",
"framework-tethering.impl",
"framework",
diff --git a/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt b/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt
index 8d8958d..d14d127 100644
--- a/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt
+++ b/tests/common/java/android/net/ConnectivitySettingsManagerTest.kt
@@ -67,6 +67,7 @@
import androidx.test.InstrumentationRegistry
import androidx.test.filters.SmallTest
import com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString
+import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import junit.framework.Assert.assertEquals
@@ -295,6 +296,7 @@
testIntValues = intArrayOf(0))
}
+ @ConnectivityModuleTest // get/setIngressRateLimitInBytesPerSecond was added via module update
@Test
fun testInternetNetworkRateLimitInBytesPerSecond() {
val defaultRate = getIngressRateLimitInBytesPerSecond(context)
diff --git a/tests/common/java/android/net/netstats/NetworkStatsCollectionTest.kt b/tests/common/java/android/net/netstats/NetworkStatsCollectionTest.kt
new file mode 100644
index 0000000..ca0e5ed
--- /dev/null
+++ b/tests/common/java/android/net/netstats/NetworkStatsCollectionTest.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netstats
+
+import android.net.NetworkIdentitySet
+import android.net.NetworkStatsCollection
+import android.net.NetworkStatsHistory
+import androidx.test.filters.SmallTest
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.SC_V2
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+import kotlin.test.fail
+
+@ConnectivityModuleTest
+@RunWith(JUnit4::class)
+@SmallTest
+class NetworkStatsCollectionTest {
+ @Rule
+ @JvmField
+ val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = SC_V2)
+
+ @Test
+ fun testBuilder() {
+ val ident = NetworkIdentitySet()
+ val key1 = NetworkStatsCollection.Key(ident, /* uid */ 0, /* set */ 0, /* tag */ 0)
+ val key2 = NetworkStatsCollection.Key(ident, /* uid */ 1, /* set */ 0, /* tag */ 0)
+ val bucketDuration = 10L
+ val entry1 = NetworkStatsHistory.Entry(10, 10, 40, 4, 50, 5, 60)
+ val entry2 = NetworkStatsHistory.Entry(30, 10, 3, 41, 7, 1, 0)
+ val history1 = NetworkStatsHistory.Builder(10, 5)
+ .addEntry(entry1)
+ .addEntry(entry2)
+ .build()
+ val history2 = NetworkStatsHistory(10, 5)
+ val actualCollection = NetworkStatsCollection.Builder(bucketDuration)
+ .addEntry(key1, history1)
+ .addEntry(key2, history2)
+ .build()
+
+ // The builder will omit any entry with empty history. Thus, only history1
+ // is expected in the result collection.
+ val actualEntries = actualCollection.entries
+ assertEquals(1, actualEntries.size)
+ val actualHistory = actualEntries[key1] ?: fail("There should be an entry for $key1")
+ assertEquals(history1.entries, actualHistory.entries)
+ }
+}
\ No newline at end of file
diff --git a/tests/common/java/android/net/netstats/NetworkStatsHistoryTest.kt b/tests/common/java/android/net/netstats/NetworkStatsHistoryTest.kt
new file mode 100644
index 0000000..c2654c5
--- /dev/null
+++ b/tests/common/java/android/net/netstats/NetworkStatsHistoryTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netstats
+
+import android.net.NetworkStatsHistory
+import android.text.format.DateUtils
+import androidx.test.filters.SmallTest
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.SC_V2
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+
+@ConnectivityModuleTest
+@RunWith(JUnit4::class)
+@SmallTest
+class NetworkStatsHistoryTest {
+ @Rule
+ @JvmField
+ val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = SC_V2)
+
+ @Test
+ fun testBuilder() {
+ val entry1 = NetworkStatsHistory.Entry(10, 30, 40, 4, 50, 5, 60)
+ val entry2 = NetworkStatsHistory.Entry(30, 15, 3, 41, 7, 1, 0)
+ val entry3 = NetworkStatsHistory.Entry(7, 301, 11, 14, 31, 2, 80)
+ val statsEmpty = NetworkStatsHistory
+ .Builder(DateUtils.HOUR_IN_MILLIS, /* initialCapacity */ 10).build()
+ assertEquals(0, statsEmpty.entries.size)
+ assertEquals(DateUtils.HOUR_IN_MILLIS, statsEmpty.bucketDuration)
+ val statsSingle = NetworkStatsHistory
+ .Builder(DateUtils.HOUR_IN_MILLIS, /* initialCapacity */ 8)
+ .addEntry(entry1)
+ .build()
+ statsSingle.assertEntriesEqual(entry1)
+ assertEquals(DateUtils.HOUR_IN_MILLIS, statsSingle.bucketDuration)
+ val statsMultiple = NetworkStatsHistory
+ .Builder(DateUtils.SECOND_IN_MILLIS, /* initialCapacity */ 0)
+ .addEntry(entry1).addEntry(entry2).addEntry(entry3)
+ .build()
+ assertEquals(DateUtils.SECOND_IN_MILLIS, statsMultiple.bucketDuration)
+ statsMultiple.assertEntriesEqual(entry1, entry2, entry3)
+ }
+
+ fun NetworkStatsHistory.assertEntriesEqual(vararg entries: NetworkStatsHistory.Entry) {
+ assertEquals(entries.size, this.entries.size)
+ entries.forEachIndexed { i, element ->
+ assertEquals(element, this.entries[i])
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/common/java/android/net/netstats/NetworkTemplateTest.kt b/tests/common/java/android/net/netstats/NetworkTemplateTest.kt
new file mode 100644
index 0000000..192694b
--- /dev/null
+++ b/tests/common/java/android/net/netstats/NetworkTemplateTest.kt
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netstats
+
+import android.net.NetworkStats.DEFAULT_NETWORK_ALL
+import android.net.NetworkStats.METERED_ALL
+import android.net.NetworkStats.METERED_YES
+import android.net.NetworkStats.ROAMING_YES
+import android.net.NetworkStats.ROAMING_ALL
+import android.net.NetworkTemplate
+import android.net.NetworkTemplate.MATCH_BLUETOOTH
+import android.net.NetworkTemplate.MATCH_CARRIER
+import android.net.NetworkTemplate.MATCH_ETHERNET
+import android.net.NetworkTemplate.MATCH_MOBILE
+import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
+import android.net.NetworkTemplate.MATCH_PROXY
+import android.net.NetworkTemplate.MATCH_WIFI
+import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
+import android.net.NetworkTemplate.NETWORK_TYPE_ALL
+import android.net.NetworkTemplate.OEM_MANAGED_ALL
+import android.telephony.TelephonyManager
+import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
+import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.SC_V2
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+private const val TEST_IMSI1 = "imsi"
+private const val TEST_WIFI_KEY1 = "wifiKey1"
+private const val TEST_WIFI_KEY2 = "wifiKey2"
+
+@RunWith(JUnit4::class)
+@ConnectivityModuleTest
+class NetworkTemplateTest {
+ @Rule
+ @JvmField
+ val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = SC_V2)
+
+ @Test
+ fun testBuilderMatchRules() {
+ // Verify unknown match rules cannot construct templates.
+ listOf(Integer.MIN_VALUE, -1, Integer.MAX_VALUE).forEach {
+ assertFailsWith<IllegalArgumentException> {
+ NetworkTemplate.Builder(it).build()
+ }
+ }
+
+ // Verify hidden match rules cannot construct templates.
+ listOf(MATCH_WIFI_WILDCARD, MATCH_MOBILE_WILDCARD, MATCH_PROXY).forEach {
+ assertFailsWith<IllegalArgumentException> {
+ NetworkTemplate.Builder(it).build()
+ }
+ }
+
+ // Verify template which matches metered cellular and carrier networks with
+ // the given IMSI. See buildTemplateMobileAll and buildTemplateCarrierMetered.
+ listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
+ NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
+ .setMeteredness(METERED_YES).build().let {
+ val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
+ arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
+ ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ assertEquals(expectedTemplate, it)
+ }
+ }
+
+ // Verify template which matches roaming cellular and carrier networks with
+ // the given IMSI.
+ listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
+ NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
+ .setRoaming(ROAMING_YES).setMeteredness(METERED_YES).build().let {
+ val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
+ arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
+ ROAMING_YES, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ assertEquals(expectedTemplate, it)
+ }
+ }
+
+ // Verify carrier template cannot be created without IMSI.
+ assertFailsWith<IllegalArgumentException> {
+ NetworkTemplate.Builder(MATCH_CARRIER).build()
+ }
+
+ // Verify template which matches metered cellular networks,
+ // regardless of IMSI. See buildTemplateMobileWildcard.
+ NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build().let {
+ val expectedTemplate = NetworkTemplate(MATCH_MOBILE_WILDCARD, null /*subscriberId*/,
+ null /*subscriberIds*/, arrayOf<String>(),
+ METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+ assertEquals(expectedTemplate, it)
+ }
+
+ // Verify template which matches metered cellular networks and ratType.
+ // See NetworkTemplate#buildTemplateMobileWithRatType.
+ NetworkTemplate.Builder(MATCH_MOBILE).setSubscriberIds(setOf(TEST_IMSI1))
+ .setMeteredness(METERED_YES).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
+ .build().let {
+ val expectedTemplate = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1,
+ arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
+ ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_UMTS,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ assertEquals(expectedTemplate, it)
+ }
+
+ // Verify template which matches all wifi networks,
+ // regardless of Wifi Network Key. See buildTemplateWifiWildcard and buildTemplateWifi.
+ NetworkTemplate.Builder(MATCH_WIFI).build().let {
+ val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
+ null /*subscriberIds*/, arrayOf<String>(),
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+ assertEquals(expectedTemplate, it)
+ }
+
+ // Verify template which matches wifi networks with the given Wifi Network Key.
+ // See buildTemplateWifi(wifiNetworkKey).
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
+ val expectedTemplate = NetworkTemplate(MATCH_WIFI, null /*subscriberId*/,
+ null /*subscriberIds*/, arrayOf(TEST_WIFI_KEY1),
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+ assertEquals(expectedTemplate, it)
+ }
+
+ // Verify template which matches all wifi networks with the
+ // given Wifi Network Key, and IMSI. See buildTemplateWifi(wifiNetworkKey, subscriberId).
+ NetworkTemplate.Builder(MATCH_WIFI).setSubscriberIds(setOf(TEST_IMSI1))
+ .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
+ val expectedTemplate = NetworkTemplate(MATCH_WIFI, TEST_IMSI1,
+ arrayOf(TEST_IMSI1), arrayOf(TEST_WIFI_KEY1),
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
+ assertEquals(expectedTemplate, it)
+ }
+
+ // Verify template which matches ethernet and bluetooth networks.
+ // See buildTemplateEthernet and buildTemplateBluetooth.
+ listOf(MATCH_ETHERNET, MATCH_BLUETOOTH).forEach { matchRule ->
+ NetworkTemplate.Builder(matchRule).build().let {
+ val expectedTemplate = NetworkTemplate(matchRule, null /*subscriberId*/,
+ null /*subscriberIds*/, arrayOf<String>(),
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+ assertEquals(expectedTemplate, it)
+ }
+ }
+ }
+
+ @Test
+ fun testBuilderWifiNetworkKeys() {
+ // Verify template builder which generates same template with the given different
+ // sequence keys.
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
+ setOf(TEST_WIFI_KEY1, TEST_WIFI_KEY2)).build().let {
+ val expectedTemplate = NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
+ setOf(TEST_WIFI_KEY2, TEST_WIFI_KEY1)).build()
+ assertEquals(expectedTemplate, it)
+ }
+
+ // Verify template which matches non-wifi networks with the given key is invalid.
+ listOf(MATCH_MOBILE, MATCH_CARRIER, MATCH_ETHERNET, MATCH_BLUETOOTH, -1,
+ Integer.MAX_VALUE).forEach { matchRule ->
+ assertFailsWith<IllegalArgumentException> {
+ NetworkTemplate.Builder(matchRule).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
+ }
+ }
+
+ // Verify template which matches wifi networks with the given null key is invalid.
+ assertFailsWith<IllegalArgumentException> {
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(null)).build()
+ }
+
+ // Verify template which matches wifi wildcard with the given empty key set.
+ NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf<String>()).build().let {
+ val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
+ arrayOf<String>() /*subscriberIds*/, arrayOf<String>(),
+ METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+ OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
+ assertEquals(expectedTemplate, it)
+ }
+ }
+}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index 1b52ec4..f82e377 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -53,6 +53,7 @@
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Bundle;
+import android.os.RemoteCallback;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.service.notification.NotificationListenerService;
@@ -140,6 +141,7 @@
private static final int ACTIVITY_NETWORK_STATE_TIMEOUT_MS = 6_000;
private static final int JOB_NETWORK_STATE_TIMEOUT_MS = 10_000;
+ private static final int LAUNCH_ACTIVITY_TIMEOUT_MS = 10_000;
// Must be higher than NETWORK_TIMEOUT_MS
private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4;
@@ -329,7 +331,8 @@
+ "; sleeping 1s before trying again");
SystemClock.sleep(SECOND_IN_MS);
}
- fail("App2 is not on background state after " + maxTries + " attempts: " + state );
+ fail("App2 (" + mUid + ") is not on background state after "
+ + maxTries + " attempts: " + state);
}
protected final void assertForegroundState() throws Exception {
@@ -347,7 +350,8 @@
turnScreenOn();
SystemClock.sleep(SECOND_IN_MS);
}
- fail("App2 is not on foreground state after " + maxTries + " attempts: " + state );
+ fail("App2 (" + mUid + ") is not on foreground state after "
+ + maxTries + " attempts: " + state);
}
protected final void assertForegroundServiceState() throws Exception {
@@ -364,7 +368,8 @@
+ "; sleeping 1s before trying again");
SystemClock.sleep(SECOND_IN_MS);
}
- fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state );
+ fail("App2 (" + mUid + ") is not on foreground service state after "
+ + maxTries + " attempts: " + state);
}
/**
@@ -406,8 +411,8 @@
// Exponential back-off.
timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS);
}
- fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries
- + " attempts.\nLast error: " + error);
+ fail("Invalid state for " + mUid + "; expectAvailable=" + expectAvailable + " after "
+ + maxTries + " attempts.\nLast error: " + error);
}
/**
@@ -763,7 +768,7 @@
Log.v(TAG, "app2 receiver is not ready yet; sleeping 1s before polling again");
SystemClock.sleep(SECOND_IN_MS);
}
- fail("app2 receiver is not ready");
+ fail("app2 receiver is not ready in " + mUid);
}
protected void registerNetworkCallback(final NetworkRequest request, INetworkCallback cb)
@@ -798,6 +803,22 @@
mDeviceIdleDeviceConfigStateHelper.restoreOriginalValues();
}
+ protected void launchActivity() throws Exception {
+ turnScreenOn();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final Intent launchIntent = getIntentForComponent(TYPE_COMPONENT_ACTIVTIY);
+ final RemoteCallback callback = new RemoteCallback(result -> latch.countDown());
+ launchIntent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
+ mContext.startActivity(launchIntent);
+ // There might be a race when app2 is launched but ACTION_FINISH_ACTIVITY has not registered
+ // before test calls finishActivity(). When the issue is happened, there is no way to fix
+ // it, so have a callback design to make sure that the app is launched completely and
+ // ACTION_FINISH_ACTIVITY will be registered before leaving this method.
+ if (!latch.await(LAUNCH_ACTIVITY_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ fail("Timed out waiting for launching activity");
+ }
+ }
+
protected void launchComponentAndAssertNetworkAccess(int type) throws Exception {
launchComponentAndAssertNetworkAccess(type, true);
}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
index cb0341c..0526a75 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java
@@ -62,6 +62,7 @@
"dumpsys network_management",
"dumpsys usagestats " + TEST_PKG + " " + TEST_APP2_PKG,
"dumpsys usagestats appstandby",
+ "dumpsys netd trafficcontroller",
}) {
dumpCommandOutput(out, cmd);
}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java
index ad7ec9e..a0d88c9 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyManagerTest.java
@@ -18,37 +18,28 @@
import static android.os.Process.SYSTEM_UID;
+import static com.android.cts.net.hostside.NetworkPolicyTestUtils.assertIsUidRestrictedOnMeteredNetworks;
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.assertNetworkingBlockedStatusForUid;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness;
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isUidNetworkingBlocked;
-import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isUidRestrictedOnMeteredNetworks;
import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground;
import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE;
import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
public class NetworkPolicyManagerTest extends AbstractRestrictBackgroundNetworkTestCase {
private static final boolean METERED = true;
private static final boolean NON_METERED = false;
- @Rule
- public final MeterednessConfigurationRule mMeterednessConfiguration =
- new MeterednessConfigurationRule();
-
@Before
public void setUp() throws Exception {
super.setUp();
- assumeTrue(canChangeActiveNetworkMeteredness());
-
registerBroadcastReceiver();
removeRestrictBackgroundWhitelist(mUid);
@@ -145,13 +136,14 @@
removeRestrictBackgroundWhitelist(mUid);
// Make TEST_APP2_PKG go to foreground and mUid will be allowed temporarily.
- launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+ launchActivity();
assertForegroundState();
assertNetworkingBlockedStatusForUid(mUid, METERED,
false /* expectedResult */); // Match NTWK_ALLOWED_TMP_ALLOWLIST
// Back to background.
finishActivity();
+ assertBackgroundState();
assertNetworkingBlockedStatusForUid(mUid, METERED,
true /* expectedResult */); // Match NTWK_BLOCKED_BG_RESTRICT
} finally {
@@ -222,26 +214,27 @@
// enabled and mUid is not in the restrict background whitelist and TEST_APP2_PKG is not
// in the foreground. For other cases, it will return false.
setRestrictBackground(true);
- assertTrue(isUidRestrictedOnMeteredNetworks(mUid));
+ assertIsUidRestrictedOnMeteredNetworks(mUid, true /* expectedResult */);
// Make TEST_APP2_PKG go to foreground and isUidRestrictedOnMeteredNetworks() will
// return false.
- launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
+ launchActivity();
assertForegroundState();
- assertFalse(isUidRestrictedOnMeteredNetworks(mUid));
+ assertIsUidRestrictedOnMeteredNetworks(mUid, false /* expectedResult */);
// Back to background.
finishActivity();
+ assertBackgroundState();
// Add mUid into restrict background whitelist and isUidRestrictedOnMeteredNetworks()
// will return false.
addRestrictBackgroundWhitelist(mUid);
- assertFalse(isUidRestrictedOnMeteredNetworks(mUid));
+ assertIsUidRestrictedOnMeteredNetworks(mUid, false /* expectedResult */);
removeRestrictBackgroundWhitelist(mUid);
} finally {
// Restrict background is disabled and isUidRestrictedOnMeteredNetworks() will return
// false.
setRestrictBackground(false);
- assertFalse(isUidRestrictedOnMeteredNetworks(mUid));
+ assertIsUidRestrictedOnMeteredNetworks(mUid, false /* expectedResult */);
}
}
}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
index 89a9bd6..9c4a348 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
@@ -439,6 +439,11 @@
PollingCheck.waitFor(() -> (expectedResult == isUidNetworkingBlocked(uid, metered)));
}
+ public static void assertIsUidRestrictedOnMeteredNetworks(int uid, boolean expectedResult)
+ throws Exception {
+ PollingCheck.waitFor(() -> (expectedResult == isUidRestrictedOnMeteredNetworks(uid)));
+ }
+
public static boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork) {
final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
try {
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java
index 5f0f6d6..4266aad 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RestrictedModeTest.java
@@ -24,6 +24,7 @@
@Before
public void setUp() throws Exception {
super.setUp();
+ setRestrictedNetworkingMode(false);
}
@After
@@ -34,8 +35,6 @@
@Test
public void testNetworkAccess() throws Exception {
- setRestrictedNetworkingMode(false);
-
// go to foreground state and enable restricted mode
launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY);
setRestrictedNetworkingMode(true);
@@ -54,4 +53,18 @@
finishActivity();
assertBackgroundNetworkAccess(true);
}
+
+ @Test
+ public void testNetworkAccess_withBatterySaver() throws Exception {
+ setBatterySaverMode(true);
+ addPowerSaveModeWhitelist(TEST_APP2_PKG);
+ assertBackgroundNetworkAccess(true);
+
+ setRestrictedNetworkingMode(true);
+ // App would be denied network access since Restricted mode is on.
+ assertBackgroundNetworkAccess(false);
+ setRestrictedNetworkingMode(false);
+ // Given that Restricted mode is turned off, app should be able to access network again.
+ assertBackgroundNetworkAccess(true);
+ }
}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index 5778b0d..7150918 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -334,9 +334,8 @@
@Nullable ProxyInfo proxyInfo,
@Nullable ArrayList<Network> underlyingNetworks, boolean isAlwaysMetered)
throws Exception {
- startVpn(addresses, routes, new String[0] /* excludedRoutes */, allowedApplications,
- disallowedApplications, proxyInfo, underlyingNetworks, isAlwaysMetered,
- false /* addRoutesByIpPrefix */);
+ startVpn(addresses, routes, excludedRoutes, allowedApplications, disallowedApplications,
+ proxyInfo, underlyingNetworks, isAlwaysMetered, false /* addRoutesByIpPrefix */);
}
private void startVpn(
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
index 6c9b469..ff7240d 100644
--- a/tests/cts/hostside/app2/AndroidManifest.xml
+++ b/tests/cts/hostside/app2/AndroidManifest.xml
@@ -22,6 +22,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!--
This application is used to listen to RESTRICT_BACKGROUND_CHANGED intents and store
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
index 9fdb9c9..eb7dca7 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java
@@ -17,7 +17,6 @@
import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_ACTIVITY;
import static com.android.cts.net.hostside.app2.Common.TAG;
-import static com.android.cts.net.hostside.app2.Common.TEST_PKG;
import static com.android.cts.net.hostside.app2.Common.TYPE_COMPONENT_ACTIVTY;
import android.app.Activity;
@@ -25,13 +24,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.RemoteException;
+import android.os.RemoteCallback;
import android.util.Log;
-import com.android.cts.net.hostside.INetworkStateObserver;
-
/**
* Activity used to bring process to foreground.
*/
@@ -51,7 +47,13 @@
MyActivity.this.finish();
}
};
- registerReceiver(finishCommandReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY));
+ registerReceiver(finishCommandReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY),
+ Context.RECEIVER_EXPORTED);
+ final RemoteCallback callback = getIntent().getParcelableExtra(
+ Intent.EXTRA_REMOTE_CALLBACK);
+ if (callback != null) {
+ callback.sendResult(null);
+ }
}
@Override
diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
index 51c3157..8c112b6 100644
--- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
+++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyJobService.java
@@ -56,7 +56,8 @@
}
}
};
- registerReceiver(mFinishCommandReceiver, new IntentFilter(ACTION_FINISH_JOB));
+ registerReceiver(mFinishCommandReceiver, new IntentFilter(ACTION_FINISH_JOB),
+ Context.RECEIVER_EXPORTED);
return true;
}
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index a95fc64..f633df4 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -330,6 +330,11 @@
"testNetworkAccess");
}
+ public void testNetworkAccess_restrictedMode_withBatterySaver() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".RestrictedModeTest",
+ "testNetworkAccess_withBatterySaver");
+ }
+
/************************
* Expedited job tests. *
************************/
diff --git a/tests/cts/net/AndroidTestTemplate.xml b/tests/cts/net/AndroidTestTemplate.xml
index d761c27..d605799 100644
--- a/tests/cts/net/AndroidTestTemplate.xml
+++ b/tests/cts/net/AndroidTestTemplate.xml
@@ -21,6 +21,8 @@
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
<option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex" />
+ <option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk" />
+ <option name="config-descriptor:metadata" key="mainline-param" value="com.google.android.tethering.apex" />
<option name="not-shardable" value="true" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index ea64252..5e8bffa 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -2174,7 +2174,7 @@
private void waitForAvailable(
@NonNull final TestableNetworkCallback cb, @NonNull final Network expectedNetwork) {
cb.expectAvailableCallbacks(expectedNetwork, false /* suspended */,
- true /* validated */,
+ null /* validated */,
false /* blocked */, NETWORK_CALLBACK_TIMEOUT_MS);
}
@@ -2908,9 +2908,8 @@
// Default network should be updated to validated cellular network.
defaultCb.eventuallyExpect(CallbackEntry.AVAILABLE, NETWORK_CALLBACK_TIMEOUT_MS,
entry -> cellNetwork.equals(entry.getNetwork()));
- // No callback except LinkPropertiesChanged which may be triggered randomly from network
- wifiCb.assertNoCallbackThat(NO_CALLBACK_TIMEOUT_MS,
- c -> !(c instanceof CallbackEntry.LinkPropertiesChanged));
+ // The network should not validate again.
+ wifiCb.assertNoCallbackThat(NO_CALLBACK_TIMEOUT_MS, c -> isValidatedCaps(c));
} finally {
resetAvoidBadWifi(previousAvoidBadWifi);
resetValidationConfig();
@@ -2919,6 +2918,12 @@
}
}
+ private boolean isValidatedCaps(CallbackEntry c) {
+ if (!(c instanceof CallbackEntry.CapabilitiesChanged)) return false;
+ final CallbackEntry.CapabilitiesChanged capsChanged = (CallbackEntry.CapabilitiesChanged) c;
+ return capsChanged.getCaps().hasCapability(NET_CAPABILITY_VALIDATED);
+ }
+
private void resetAvoidBadWifi(int settingValue) {
setTestAllowBadWifiResource(0 /* timeMs */);
ConnectivitySettingsManager.setNetworkAvoidBadWifi(mContext, settingValue);
@@ -3259,6 +3264,19 @@
assertTrue(dumpOutput, dumpOutput.contains("Active default network"));
}
+ @Test @IgnoreUpTo(SC_V2)
+ public void testDumpBpfNetMaps() throws Exception {
+ final String[] args = new String[] {"--short", "trafficcontroller"};
+ String dumpOutput = DumpTestUtils.dumpServiceWithShellPermission(
+ Context.CONNECTIVITY_SERVICE, args);
+ assertTrue(dumpOutput, dumpOutput.contains("TrafficController"));
+ assertFalse(dumpOutput, dumpOutput.contains("BPF map content"));
+
+ dumpOutput = DumpTestUtils.dumpServiceWithShellPermission(
+ Context.CONNECTIVITY_SERVICE, args[1]);
+ assertTrue(dumpOutput, dumpOutput.contains("BPF map content"));
+ }
+
private void unregisterRegisteredCallbacks() {
for (NetworkCallback callback: mRegisteredCallbacks) {
mCm.unregisterNetworkCallback(callback);
diff --git a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
index 886b078..ea98289 100644
--- a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
+++ b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
@@ -75,6 +75,7 @@
import com.android.testutils.TestableNetworkCallback
import org.junit.After
import org.junit.AfterClass
+import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Rule
@@ -88,6 +89,7 @@
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.UUID
+import java.util.regex.Pattern
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
@@ -125,8 +127,25 @@
private lateinit var tunNetworkCallback: TestNetworkCallback
private lateinit var reader: TapPacketReader
+ private fun getKernelVersion(): IntArray {
+ // Example:
+ // 4.9.29-g958411d --> 4.9
+ val release = Os.uname().release
+ val m = Pattern.compile("^(\\d+)\\.(\\d+)").matcher(release)
+ assertTrue(m.find(), "No pattern in release string: " + release)
+ return intArrayOf(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)))
+ }
+
+ private fun kernelIsAtLeast(major: Int, minor: Int): Boolean {
+ val version = getKernelVersion()
+ return (version.get(0) > major || (version.get(0) == major && version.get(1) >= minor))
+ }
+
@Before
fun setUp() {
+ // For BPF support kernel needs to be at least 5.4.
+ assumeTrue(kernelIsAtLeast(5, 4))
+
runAsShell(MANAGE_TEST_NETWORKS) {
val tnm = realContext.getSystemService(TestNetworkManager::class.java)
diff --git a/tests/cts/net/src/android/net/cts/EthernetNetworkSpecifierTest.java b/tests/cts/net/src/android/net/cts/EthernetNetworkSpecifierTest.java
new file mode 100644
index 0000000..ef8fd1a
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/EthernetNetworkSpecifierTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThrows;
+
+import android.net.EthernetNetworkSpecifier;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@IgnoreUpTo(Build.VERSION_CODES.R)
+@RunWith(DevSdkIgnoreRunner.class)
+public class EthernetNetworkSpecifierTest {
+
+ @Test
+ public void testConstructor() {
+ final String iface = "testIface";
+ final EthernetNetworkSpecifier ns = new EthernetNetworkSpecifier(iface);
+ assertEquals(iface, ns.getInterfaceName());
+ }
+
+ @Test
+ public void testConstructorWithNullValue() {
+ assertThrows("Should not be able to call constructor with null value.",
+ IllegalArgumentException.class,
+ () -> new EthernetNetworkSpecifier(null));
+ }
+
+ @Test
+ public void testConstructorWithEmptyValue() {
+ assertThrows("Should not be able to call constructor with empty value.",
+ IllegalArgumentException.class,
+ () -> new EthernetNetworkSpecifier(""));
+ }
+
+ @Test
+ public void testEquals() {
+ final String iface = "testIface";
+ final EthernetNetworkSpecifier nsOne = new EthernetNetworkSpecifier(iface);
+ final EthernetNetworkSpecifier nsTwo = new EthernetNetworkSpecifier(iface);
+ assertEquals(nsOne, nsTwo);
+ }
+
+ @Test
+ public void testNotEquals() {
+ final String iface = "testIface";
+ final String ifaceTwo = "testIfaceTwo";
+ final EthernetNetworkSpecifier nsOne = new EthernetNetworkSpecifier(iface);
+ final EthernetNetworkSpecifier nsTwo = new EthernetNetworkSpecifier(ifaceTwo);
+ assertNotEquals(nsOne, nsTwo);
+ }
+}
diff --git a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
index d221694..1d19d26 100644
--- a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
+++ b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java
@@ -29,6 +29,7 @@
import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.ConnectivityModuleTest;
import com.android.testutils.DevSdkIgnoreRule;
import libcore.net.InetAddressUtils;
@@ -106,6 +107,10 @@
assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig));
}
+ @ConnectivityModuleTest // The builder was added in an S+ module update.
+ // This whole class is not skipped (marked @ConnectivityModuleTest) in MTS for non-connectivity
+ // modules like NetworkStack, as NetworkStack uses IpConfiguration a lot on Q+, so tests that
+ // cover older APIs are still useful to provide used API coverage for NetworkStack.
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
@Test
public void testBuilder() {
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 344482b..225602f 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -77,6 +77,7 @@
import com.android.modules.utils.build.SdkLevel
import com.android.net.module.util.ArrayTrackRecord
import com.android.testutils.CompatUtil
+import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import com.android.testutils.RecorderCallback.CallbackEntry.Available
@@ -153,6 +154,10 @@
// NetworkAgent is not updatable in R-, so this test does not need to be compatible with older
// versions. NetworkAgent was also based on AsyncChannel before S so cannot be tested the same way.
@IgnoreUpTo(Build.VERSION_CODES.R)
+// NetworkAgent is updated as part of the connectivity module, and running NetworkAgent tests in MTS
+// for modules other than Connectivity does not provide much value. Only run them in connectivity
+// module MTS, so the tests only need to cover the case of an updated NetworkAgent.
+@ConnectivityModuleTest
class NetworkAgentTest {
private val LOCAL_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1")
private val REMOTE_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.2")
@@ -467,7 +472,7 @@
@Test
fun testRejectedUpdates() {
- val callback = TestableNetworkCallback()
+ val callback = TestableNetworkCallback(DEFAULT_TIMEOUT_MS)
// will be cleaned up in tearDown
registerNetworkCallback(makeTestNetworkRequest(), callback)
val agent = createNetworkAgent(initialNc = ncWithAccessUids(200))
diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
index 147fca9..de4f41b 100644
--- a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
@@ -21,11 +21,19 @@
import static android.app.usage.NetworkStats.Bucket.METERED_ALL;
import static android.app.usage.NetworkStats.Bucket.METERED_NO;
import static android.app.usage.NetworkStats.Bucket.METERED_YES;
+import static android.app.usage.NetworkStats.Bucket.ROAMING_ALL;
+import static android.app.usage.NetworkStats.Bucket.ROAMING_NO;
+import static android.app.usage.NetworkStats.Bucket.ROAMING_YES;
import static android.app.usage.NetworkStats.Bucket.STATE_ALL;
import static android.app.usage.NetworkStats.Bucket.STATE_DEFAULT;
import static android.app.usage.NetworkStats.Bucket.STATE_FOREGROUND;
import static android.app.usage.NetworkStats.Bucket.TAG_NONE;
import static android.app.usage.NetworkStats.Bucket.UID_ALL;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
+import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
import android.app.AppOpsManager;
import android.app.usage.NetworkStats;
@@ -37,7 +45,10 @@
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
+import android.net.NetworkStatsCollection;
+import android.net.NetworkStatsHistory;
import android.net.TrafficStats;
+import android.net.netstats.NetworkStatsDataMigrationUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
@@ -46,10 +57,13 @@
import android.platform.test.annotations.AppModeFull;
import android.telephony.TelephonyManager;
import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
import android.util.Log;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.testutils.DevSdkIgnoreRule;
import java.io.IOException;
import java.io.InputStream;
@@ -59,6 +73,10 @@
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
public class NetworkStatsManagerTest extends InstrumentationTestCase {
private static final String LOG_TAG = "NetworkStatsManagerTest";
@@ -77,6 +95,7 @@
private abstract class NetworkInterfaceToTest {
private boolean mMetered;
+ private boolean mRoaming;
private boolean mIsDefault;
abstract int getNetworkType();
@@ -90,6 +109,14 @@
this.mMetered = metered;
}
+ public boolean getRoaming() {
+ return mRoaming;
+ }
+
+ public void setRoaming(boolean roaming) {
+ this.mRoaming = roaming;
+ }
+
public boolean getIsDefault() {
return mIsDefault;
}
@@ -267,6 +294,7 @@
private URL mUrl;
public boolean success;
public boolean metered;
+ public boolean roaming;
public boolean isDefault;
NetworkCallback(long tolerance, URL url) {
@@ -274,6 +302,7 @@
mUrl = url;
success = false;
metered = false;
+ roaming = false;
isDefault = false;
}
@@ -303,6 +332,8 @@
success = true;
metered = !mCm.getNetworkCapabilities(network)
.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ roaming = !mCm.getNetworkCapabilities(network)
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
synchronized (NetworkStatsManagerTest.this) {
NetworkStatsManagerTest.this.notify();
}
@@ -333,6 +364,7 @@
}
if (callback.success) {
mNetworkInterfacesToTest[networkTypeIndex].setMetered(callback.metered);
+ mNetworkInterfacesToTest[networkTypeIndex].setRoaming(callback.roaming);
mNetworkInterfacesToTest[networkTypeIndex].setIsDefault(callback.isDefault);
return true;
}
@@ -377,6 +409,7 @@
assertEquals(bucket.getState(), STATE_ALL);
assertEquals(bucket.getUid(), UID_ALL);
assertEquals(bucket.getMetered(), METERED_ALL);
+ assertEquals(bucket.getRoaming(), ROAMING_ALL);
assertEquals(bucket.getDefaultNetworkStatus(), DEFAULT_NETWORK_ALL);
setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
try {
@@ -412,6 +445,7 @@
assertEquals(bucket.getState(), STATE_ALL);
assertEquals(bucket.getUid(), UID_ALL);
assertEquals(bucket.getMetered(), METERED_ALL);
+ assertEquals(bucket.getRoaming(), ROAMING_ALL);
assertEquals(bucket.getDefaultNetworkStatus(), DEFAULT_NETWORK_ALL);
setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
try {
@@ -451,15 +485,19 @@
long totalTxBytes = 0;
long totalRxBytes = 0;
boolean hasCorrectMetering = false;
+ boolean hasCorrectRoaming = false;
boolean hasCorrectDefaultStatus = false;
int expectedMetering = mNetworkInterfacesToTest[i].getMetered()
? METERED_YES : METERED_NO;
+ int expectedRoaming = mNetworkInterfacesToTest[i].getRoaming()
+ ? ROAMING_YES : ROAMING_NO;
int expectedDefaultStatus = mNetworkInterfacesToTest[i].getIsDefault()
? DEFAULT_NETWORK_YES : DEFAULT_NETWORK_NO;
while (result.hasNextBucket()) {
assertTrue(result.getNextBucket(bucket));
assertTimestamps(bucket);
hasCorrectMetering |= bucket.getMetered() == expectedMetering;
+ hasCorrectRoaming |= bucket.getRoaming() == expectedRoaming;
if (bucket.getUid() == Process.myUid()) {
totalTxPackets += bucket.getTxPackets();
totalRxPackets += bucket.getRxPackets();
@@ -472,6 +510,8 @@
assertFalse(result.getNextBucket(bucket));
assertTrue("Incorrect metering for NetworkType: "
+ mNetworkInterfacesToTest[i].getNetworkType(), hasCorrectMetering);
+ assertTrue("Incorrect roaming for NetworkType: "
+ + mNetworkInterfacesToTest[i].getNetworkType(), hasCorrectRoaming);
assertTrue("Incorrect isDefault for NetworkType: "
+ mNetworkInterfacesToTest[i].getNetworkType(), hasCorrectDefaultStatus);
assertTrue("No Rx bytes usage for uid " + Process.myUid(), totalRxBytes > 0);
@@ -564,6 +604,7 @@
assertTimestamps(bucket);
assertEquals(bucket.getState(), STATE_ALL);
assertEquals(bucket.getMetered(), METERED_ALL);
+ assertEquals(bucket.getRoaming(), ROAMING_ALL);
assertEquals(bucket.getDefaultNetworkStatus(), DEFAULT_NETWORK_ALL);
assertEquals(bucket.getUid(), Process.myUid());
totalTxPackets += bucket.getTxPackets();
@@ -617,6 +658,7 @@
assertTimestamps(bucket);
assertEquals(bucket.getState(), STATE_ALL);
assertEquals(bucket.getMetered(), METERED_ALL);
+ assertEquals(bucket.getRoaming(), ROAMING_ALL);
assertEquals(bucket.getDefaultNetworkStatus(), DEFAULT_NETWORK_ALL);
assertEquals(bucket.getUid(), Process.myUid());
if (bucket.getTag() == NETWORK_TAG) {
@@ -798,6 +840,43 @@
// storing files of >2MB in CTS.
mNsm.unregisterUsageCallback(usageCallback);
+
+ // For T- devices, the registerUsageCallback invocation below will need a looper
+ // from the thread that calls into the API, which is not available in the test.
+ if (SdkLevel.isAtLeastT()) {
+ mNsm.registerUsageCallback(mNetworkInterfacesToTest[i].getNetworkType(),
+ getSubscriberId(i), THRESHOLD_BYTES, usageCallback);
+ mNsm.unregisterUsageCallback(usageCallback);
+ }
+ }
+ }
+
+ @AppModeFull
+ @DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+ public void testDataMigrationUtils() throws Exception {
+ final List<String> prefixes = List.of(PREFIX_UID, PREFIX_XT, PREFIX_UID_TAG);
+ for (final String prefix : prefixes) {
+ final long duration = TextUtils.equals(PREFIX_XT, prefix) ? TimeUnit.HOURS.toMillis(1)
+ : TimeUnit.HOURS.toMillis(2);
+
+ final NetworkStatsCollection collection =
+ NetworkStatsDataMigrationUtils.readPlatformCollection(prefix, duration);
+
+ final long now = System.currentTimeMillis();
+ final Set<Map.Entry<NetworkStatsCollection.Key, NetworkStatsHistory>> entries =
+ collection.getEntries().entrySet();
+ for (final Map.Entry<NetworkStatsCollection.Key, NetworkStatsHistory> entry : entries) {
+ for (final NetworkStatsHistory.Entry historyEntry : entry.getValue().getEntries()) {
+ // Verify all value fields are reasonable.
+ assertTrue(historyEntry.getBucketStart() <= now);
+ assertTrue(historyEntry.getActiveTime() <= duration);
+ assertTrue(historyEntry.getRxBytes() >= 0);
+ assertTrue(historyEntry.getRxPackets() >= 0);
+ assertTrue(historyEntry.getTxBytes() >= 0);
+ assertTrue(historyEntry.getTxPackets() >= 0);
+ assertTrue(historyEntry.getOperations() >= 0);
+ }
+ }
}
}
@@ -838,6 +917,7 @@
if (expectedTag != null) assertEquals(bucket.getTag(), (int) expectedTag);
if (expectedState != null) assertEquals(bucket.getState(), (int) expectedState);
assertEquals(bucket.getMetered(), METERED_ALL);
+ assertEquals(bucket.getRoaming(), ROAMING_ALL);
assertEquals(bucket.getDefaultNetworkStatus(), DEFAULT_NETWORK_ALL);
if (bucket.getUid() == Process.myUid()) {
totalTxPackets += bucket.getTxPackets();
diff --git a/tests/cts/net/src/android/net/cts/RateLimitTest.java b/tests/cts/net/src/android/net/cts/RateLimitTest.java
new file mode 100644
index 0000000..8a3db26
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/RateLimitTest.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
+import static android.system.OsConstants.IPPROTO_IP;
+import static android.system.OsConstants.IPPROTO_UDP;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU;
+import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY;
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+import static com.android.testutils.TestPermissionUtil.runAsShell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.icu.text.MessageFormat;
+import android.net.ConnectivityManager;
+import android.net.ConnectivitySettingsManager;
+import android.net.InetAddresses;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkAgentConfig;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.RouteInfo;
+import android.net.TestNetworkInterface;
+import android.net.TestNetworkManager;
+import android.net.TestNetworkSpecifier;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.platform.test.annotations.AppModeFull;
+import android.system.Os;
+import android.util.Log;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.net.module.util.PacketBuilder;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+import com.android.testutils.TestableNetworkAgent;
+import com.android.testutils.TestableNetworkCallback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.SocketTimeoutException;
+import java.nio.ByteBuffer;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.stream.Collectors;
+
+@AppModeFull(reason = "Instant apps cannot access /dev/tun, so createTunInterface fails")
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class RateLimitTest {
+ private static final String TAG = "RateLimitTest";
+ private static final LinkAddress LOCAL_IP4_ADDR = new LinkAddress("10.0.0.1/8");
+ private static final InetAddress REMOTE_IP4_ADDR = InetAddresses.parseNumericAddress("8.8.8.8");
+ private static final short TEST_UDP_PORT = 1234;
+ private static final byte TOS = 0;
+ private static final short ID = 27149;
+ private static final short DONT_FRAG_FLAG_MASK = (short) 0x4000; // flags=DF, offset=0
+ private static final byte TIME_TO_LIVE = 64;
+ private static final byte[] PAYLOAD = new byte[1472];
+
+ private Handler mHandler;
+ private Context mContext;
+ private TestNetworkManager mNetworkManager;
+ private TestNetworkInterface mTunInterface;
+ private ConnectivityManager mCm;
+ private TestNetworkSpecifier mNetworkSpecifier;
+ private NetworkCapabilities mNetworkCapabilities;
+ private TestableNetworkCallback mNetworkCallback;
+ private LinkProperties mLinkProperties;
+ private TestableNetworkAgent mNetworkAgent;
+ private Network mNetwork;
+ private DatagramSocket mSocket;
+
+ @BeforeClass
+ public static void assumeKernelSupport() {
+ final String result = SystemUtil.runShellCommandOrThrow("gzip -cd /proc/config.gz");
+ HashSet<String> kernelConfig = Arrays.stream(result.split("\\R")).collect(
+ Collectors.toCollection(HashSet::new));
+
+ // make sure that if for some reason /proc/config.gz returns an empty string, this test
+ // does not silently fail.
+ assertNotEquals(0, result.length());
+
+ assumeTrue(kernelConfig.contains("CONFIG_NET_CLS_MATCHALL=y"));
+ assumeTrue(kernelConfig.contains("CONFIG_NET_ACT_POLICE=y"));
+ assumeTrue(kernelConfig.contains("CONFIG_NET_ACT_BPF=y"));
+ }
+
+ @Before
+ public void setUp() throws IOException {
+ mHandler = new Handler(Looper.getMainLooper());
+
+ runAsShell(MANAGE_TEST_NETWORKS, () -> {
+ mContext = getContext();
+
+ mNetworkManager = mContext.getSystemService(TestNetworkManager.class);
+ mTunInterface = mNetworkManager.createTunInterface(Arrays.asList(LOCAL_IP4_ADDR));
+ });
+
+ mCm = mContext.getSystemService(ConnectivityManager.class);
+ mNetworkSpecifier = new TestNetworkSpecifier(mTunInterface.getInterfaceName());
+ mNetworkCapabilities = new NetworkCapabilities.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
+ .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+ .setNetworkSpecifier(mNetworkSpecifier).build();
+ mNetworkCallback = new TestableNetworkCallback();
+
+ mCm.requestNetwork(
+ new NetworkRequest.Builder()
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+ .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
+ .setNetworkSpecifier(mNetworkSpecifier)
+ .build(),
+ mNetworkCallback);
+
+ mLinkProperties = new LinkProperties();
+ mLinkProperties.addLinkAddress(LOCAL_IP4_ADDR);
+ mLinkProperties.setInterfaceName(mTunInterface.getInterfaceName());
+ mLinkProperties.addRoute(
+ new RouteInfo(new IpPrefix(IPV4_ADDR_ANY, 0), null,
+ mTunInterface.getInterfaceName()));
+
+
+ runAsShell(MANAGE_TEST_NETWORKS, () -> {
+ mNetworkAgent = new TestableNetworkAgent(mContext, mHandler.getLooper(),
+ mNetworkCapabilities, mLinkProperties,
+ new NetworkAgentConfig.Builder().setExplicitlySelected(
+ true).setUnvalidatedConnectivityAcceptable(true).build());
+
+ mNetworkAgent.register();
+ mNetworkAgent.markConnected();
+ });
+
+ mNetwork = mNetworkAgent.getNetwork();
+ mNetworkCallback.expectAvailableThenValidatedCallbacks(mNetwork, 5_000);
+ mSocket = new DatagramSocket(TEST_UDP_PORT);
+ mSocket.setSoTimeout(1_000);
+ mNetwork.bindSocket(mSocket);
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ // whatever happens, don't leave the device in rate limited state.
+ ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mContext, -1);
+ mSocket.close();
+ mNetworkAgent.unregister();
+ mTunInterface.getFileDescriptor().close();
+ mCm.unregisterNetworkCallback(mNetworkCallback);
+ }
+
+ private void assertGreaterThan(final String msg, long lhs, long rhs) {
+ assertTrue(msg + " -- Failed comparison: " + lhs + " > " + rhs, lhs > rhs);
+ }
+
+ private void assertLessThan(final String msg, long lhs, long rhs) {
+ assertTrue(msg + " -- Failed comparison: " + lhs + " < " + rhs, lhs < rhs);
+ }
+
+ private static void sendPacketsToTunInterfaceForDuration(final TestNetworkInterface iface,
+ final Duration duration) throws Exception {
+ final ByteBuffer buffer = PacketBuilder.allocate(false, IPPROTO_IP, IPPROTO_UDP,
+ PAYLOAD.length);
+ final PacketBuilder builder = new PacketBuilder(buffer);
+ builder.writeIpv4Header(TOS, ID, DONT_FRAG_FLAG_MASK, TIME_TO_LIVE,
+ (byte) IPPROTO_UDP, (Inet4Address) REMOTE_IP4_ADDR,
+ (Inet4Address) LOCAL_IP4_ADDR.getAddress());
+ builder.writeUdpHeader((short) TEST_UDP_PORT, (short) TEST_UDP_PORT);
+ buffer.put(PAYLOAD);
+ builder.finalizePacket();
+
+ // write packets to the tun fd as fast as possible for duration.
+ long endMillis = SystemClock.elapsedRealtime() + duration.toMillis();
+ while (SystemClock.elapsedRealtime() < endMillis) {
+ Os.write(iface.getFileDescriptor().getFileDescriptor(), buffer.array(), 0,
+ buffer.limit());
+ }
+ }
+
+ private static class RateMeasurementSocketReader extends Thread {
+ private volatile boolean mIsRunning = false;
+ private DatagramSocket mSocket;
+ private long mStartMillis = 0;
+ private long mStopMillis = 0;
+ private long mBytesReceived = 0;
+
+ RateMeasurementSocketReader(DatagramSocket socket) throws Exception {
+ mSocket = socket;
+ }
+
+ public void startTest() {
+ mIsRunning = true;
+ start();
+ }
+
+ public long stopAndGetResult() throws Exception {
+ mIsRunning = false;
+ join();
+
+ final long durationMillis = mStopMillis - mStartMillis;
+ return (long) ((double) mBytesReceived / (durationMillis / 1000.0));
+ }
+
+ @Override
+ public void run() {
+ // Since the actual data is not used, the buffer can just be recycled.
+ final byte[] recvBuf = new byte[ETHER_MTU];
+ final DatagramPacket receivedPacket = new DatagramPacket(recvBuf, recvBuf.length);
+ while (mIsRunning) {
+ try {
+ mSocket.receive(receivedPacket);
+
+ // don't start the test until after the first packet is received and increment
+ // mBytesReceived starting with the second packet.
+ long time = SystemClock.elapsedRealtime();
+ if (mStartMillis == 0) {
+ mStartMillis = time;
+ } else {
+ mBytesReceived += receivedPacket.getLength();
+ }
+ // there may not be another packet, update the stop time on every iteration.
+ mStopMillis = time;
+ } catch (SocketTimeoutException e) {
+ // sender has stopped sending data, do nothing and return.
+ } catch (IOException e) {
+ Log.e(TAG, "socket receive failed", e);
+ }
+ }
+ }
+ }
+
+ private long runIngressDataRateMeasurement(final Duration testDuration) throws Exception {
+ final RateMeasurementSocketReader reader = new RateMeasurementSocketReader(mSocket);
+ reader.startTest();
+ sendPacketsToTunInterfaceForDuration(mTunInterface, testDuration);
+ return reader.stopAndGetResult();
+ }
+
+ void waitForTcPoliceFilterInstalled(Duration timeout) throws IOException {
+ final String command = MessageFormat.format("tc filter show ingress dev {0}",
+ mTunInterface.getInterfaceName());
+ // wait for tc police to show up
+ final long startTime = SystemClock.elapsedRealtime();
+ final long timeoutTime = startTime + timeout.toMillis();
+ while (!SystemUtil.runShellCommand(command).contains("police")) {
+ assertLessThan("timed out waiting for tc police filter",
+ SystemClock.elapsedRealtime(), timeoutTime);
+ SystemClock.sleep(10);
+ }
+ Log.v(TAG, "waited " + (SystemClock.elapsedRealtime() - startTime)
+ + "ms for tc police filter to appear");
+ }
+
+ @Test
+ public void testIngressRateLimit_testLimit() throws Exception {
+ // If this value is too low, this test might become flaky because of the burst value that
+ // allows to send at a higher data rate for a short period of time. The faster the data rate
+ // and the longer the test, the less this test will be affected.
+ final long dataLimitInBytesPerSecond = 1_000_000; // 1MB/s
+ long resultInBytesPerSecond = runIngressDataRateMeasurement(Duration.ofSeconds(1));
+ assertGreaterThan("Failed initial test with rate limit disabled", resultInBytesPerSecond,
+ dataLimitInBytesPerSecond);
+
+ // enable rate limit and wait until the tc filter is installed before starting the test.
+ ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mContext,
+ dataLimitInBytesPerSecond);
+ waitForTcPoliceFilterInstalled(Duration.ofSeconds(1));
+
+ resultInBytesPerSecond = runIngressDataRateMeasurement(Duration.ofSeconds(10));
+ // Add 1% tolerance to reduce test flakiness. Burst size is constant at 128KiB.
+ assertLessThan("Failed test with rate limit enabled", resultInBytesPerSecond,
+ (long) (dataLimitInBytesPerSecond * 1.01));
+
+ ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mContext, -1);
+
+ resultInBytesPerSecond = runIngressDataRateMeasurement(Duration.ofSeconds(1));
+ assertGreaterThan("Failed test with rate limit disabled", resultInBytesPerSecond,
+ dataLimitInBytesPerSecond);
+ }
+
+ @Test
+ public void testIngressRateLimit_testSetting() {
+ int dataLimitInBytesPerSecond = 1_000_000;
+ ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mContext,
+ dataLimitInBytesPerSecond);
+ assertEquals(dataLimitInBytesPerSecond,
+ ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond(mContext));
+ ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mContext, -1);
+ assertEquals(-1,
+ ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond(mContext));
+ }
+}
diff --git a/tests/cts/net/src/android/net/cts/StaticIpConfigurationTest.java b/tests/cts/net/src/android/net/cts/StaticIpConfigurationTest.java
index 9b2756c..e2d3346 100644
--- a/tests/cts/net/src/android/net/cts/StaticIpConfigurationTest.java
+++ b/tests/cts/net/src/android/net/cts/StaticIpConfigurationTest.java
@@ -35,6 +35,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.ConnectivityModuleTest;
import com.android.testutils.DevSdkIgnoreRule;
import org.junit.Rule;
@@ -256,7 +257,7 @@
assertEquals(DNS1, s.getDnsServers().get(0));
}
- @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+ @ConnectivityModuleTest @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
@Test
public void testIllegalBuilders() {
assertThrows("Can't set IP Address to IPv6!", IllegalArgumentException.class, () -> {
diff --git a/tests/deflake/Android.bp b/tests/deflake/Android.bp
index b3d0363..8205f1c 100644
--- a/tests/deflake/Android.bp
+++ b/tests/deflake/Android.bp
@@ -21,7 +21,7 @@
// FrameworksNetDeflakeTest depends on FrameworksNetTests so it should be disabled
// if FrameworksNetTests is disabled.
-enable_frameworks_net_deflake_test = false
+enable_frameworks_net_deflake_test = true
// Placeholder
// This is a placeholder comment to minimize merge conflicts, as enable_frameworks_net_deflake_test
// may have different values depending on the branch
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index 530fa91..97c1265 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -40,7 +40,7 @@
"mockito-target-extended-minus-junit4",
"net-tests-utils",
"service-connectivity-pre-jarjar",
- "services.core",
+ "service-connectivity-tiramisu-pre-jarjar",
"services.net",
"testables",
],
diff --git a/tests/mts/Android.bp b/tests/mts/Android.bp
index 2c44010..74fee3d 100644
--- a/tests/mts/Android.bp
+++ b/tests/mts/Android.bp
@@ -27,6 +27,9 @@
"connectivity-mainline-presubmit-cc-defaults",
],
require_root: true,
+ header_libs: [
+ "bpf_headers",
+ ],
static_libs: [
"libbase",
"libmodules-utils-build",
diff --git a/tests/mts/bpf_existence_test.cpp b/tests/mts/bpf_existence_test.cpp
index 142e013..2bba282 100644
--- a/tests/mts/bpf_existence_test.cpp
+++ b/tests/mts/bpf_existence_test.cpp
@@ -23,6 +23,7 @@
#include <android/api-level.h>
#include <android-base/properties.h>
#include <android-modules-utils/sdk_level.h>
+#include <bpf/BpfUtils.h>
#include <gtest/gtest.h>
@@ -151,6 +152,8 @@
}
TEST_F(BpfExistenceTest, TestPrograms) {
+ SKIP_IF_BPF_NOT_SUPPORTED;
+
// Pre-flight check to ensure test has been updated.
uint64_t buildVersionSdk = android_get_device_api_level();
ASSERT_NE(0, buildVersionSdk) << "Unable to determine device SDK version";
diff --git a/tests/smoketest/Android.bp b/tests/smoketest/Android.bp
index 8011540..df8ab74 100644
--- a/tests/smoketest/Android.bp
+++ b/tests/smoketest/Android.bp
@@ -22,6 +22,6 @@
static_libs: [
"androidx.test.rules",
"mockito-target-minus-junit4",
- "services.core",
+ "service-connectivity",
],
}
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 038f434..eaceb9a 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -13,7 +13,7 @@
// Whether to enable the FrameworksNetTests. Set to false in the branches that might have older
// frameworks/base since FrameworksNetTests includes the test for classes that are not in
// connectivity module.
-enable_frameworks_net_tests = false
+enable_frameworks_net_tests = true
// Placeholder
// This is a placeholder comment to minimize merge conflicts, as enable_frameworks_net_tests
// may have different values depending on the branch
@@ -167,6 +167,7 @@
"services.net",
],
jni_libs: [
+ "libandroid_net_connectivity_com_android_net_module_util_jni",
"libservice-connectivity",
"libandroid_net_connectivity_com_android_net_module_util_jni",
],
diff --git a/tests/unit/java/android/net/NetworkIdentityTest.kt b/tests/unit/java/android/net/NetworkIdentityTest.kt
index 4b2d874..bf5568d 100644
--- a/tests/unit/java/android/net/NetworkIdentityTest.kt
+++ b/tests/unit/java/android/net/NetworkIdentityTest.kt
@@ -22,6 +22,7 @@
import android.net.ConnectivityManager.TYPE_MOBILE
import android.net.ConnectivityManager.TYPE_NONE
import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkIdentity.OEM_NONE
import android.net.NetworkIdentity.OEM_PAID
import android.net.NetworkIdentity.OEM_PRIVATE
@@ -39,8 +40,11 @@
import kotlin.test.assertFalse
import kotlin.test.assertTrue
-private const val TEST_IMSI = "testimsi"
private const val TEST_WIFI_KEY = "testwifikey"
+private const val TEST_IMSI1 = "testimsi1"
+private const val TEST_IMSI2 = "testimsi2"
+private const val TEST_SUBID1 = 1
+private const val TEST_SUBID2 = 2
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
@@ -84,7 +88,7 @@
fun testIsMetered() {
// Verify network is metered.
val netIdent1 = NetworkIdentity.buildNetworkIdentity(mockContext,
- buildMobileNetworkStateSnapshot(NetworkCapabilities(), TEST_IMSI),
+ buildMobileNetworkStateSnapshot(NetworkCapabilities(), TEST_IMSI1),
false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
assertTrue(netIdent1.isMetered())
@@ -93,7 +97,7 @@
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
}.build()
val netIdent2 = NetworkIdentity.buildNetworkIdentity(mockContext,
- buildMobileNetworkStateSnapshot(capsNotMetered, TEST_IMSI),
+ buildMobileNetworkStateSnapshot(capsNotMetered, TEST_IMSI1),
false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
assertFalse(netIdent2.isMetered())
@@ -103,33 +107,38 @@
setCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED, true)
}
val netIdent3 = NetworkIdentity.buildNetworkIdentity(mockContext,
- buildMobileNetworkStateSnapshot(capsTempNotMetered, TEST_IMSI),
+ buildMobileNetworkStateSnapshot(capsTempNotMetered, TEST_IMSI1),
false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
assertFalse(netIdent3.isMetered())
}
@Test
fun testBuilder() {
+ val specifier1 = TelephonyNetworkSpecifier(TEST_SUBID1)
val oemPrivateRoamingNotMeteredCap = NetworkCapabilities().apply {
addCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+ addTransportType(TRANSPORT_CELLULAR)
+ setNetworkSpecifier(specifier1)
}
val identFromSnapshot = NetworkIdentity.Builder().setNetworkStateSnapshot(
- buildMobileNetworkStateSnapshot(oemPrivateRoamingNotMeteredCap, TEST_IMSI))
+ buildMobileNetworkStateSnapshot(oemPrivateRoamingNotMeteredCap, TEST_IMSI1))
.setDefaultNetwork(true)
.setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
+ .setSubId(TEST_SUBID1)
.build()
val identFromLegacyBuild = NetworkIdentity.buildNetworkIdentity(mockContext,
- buildMobileNetworkStateSnapshot(oemPrivateRoamingNotMeteredCap, TEST_IMSI),
+ buildMobileNetworkStateSnapshot(oemPrivateRoamingNotMeteredCap, TEST_IMSI1),
true /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
val identFromConstructor = NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UMTS,
- TEST_IMSI,
+ TEST_IMSI1,
null /* wifiNetworkKey */,
true /* roaming */,
false /* metered */,
true /* defaultNetwork */,
- NetworkTemplate.OEM_MANAGED_PRIVATE)
+ NetworkTemplate.OEM_MANAGED_PRIVATE,
+ TEST_SUBID1)
assertEquals(identFromLegacyBuild, identFromSnapshot)
assertEquals(identFromConstructor, identFromSnapshot)
@@ -222,4 +231,28 @@
}
}
}
+
+ @Test
+ fun testGetSubId() {
+ val specifier1 = TelephonyNetworkSpecifier(TEST_SUBID1)
+ val specifier2 = TelephonyNetworkSpecifier(TEST_SUBID2)
+ val capSUBID1 = NetworkCapabilities().apply {
+ addTransportType(TRANSPORT_CELLULAR)
+ setNetworkSpecifier(specifier1)
+ }
+ val capSUBID2 = NetworkCapabilities().apply {
+ addTransportType(TRANSPORT_CELLULAR)
+ setNetworkSpecifier(specifier2)
+ }
+
+ val netIdent1 = NetworkIdentity.buildNetworkIdentity(mockContext,
+ buildMobileNetworkStateSnapshot(capSUBID1, TEST_IMSI1),
+ false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
+ assertEquals(TEST_SUBID1, netIdent1.getSubId())
+
+ val netIdent2 = NetworkIdentity.buildNetworkIdentity(mockContext,
+ buildMobileNetworkStateSnapshot(capSUBID2, TEST_IMSI2),
+ false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
+ assertEquals(TEST_SUBID2, netIdent2.getSubId())
+ }
}
diff --git a/tests/unit/java/android/net/NetworkStatsCollectionTest.java b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
index c27ee93..0f02850 100644
--- a/tests/unit/java/android/net/NetworkStatsCollectionTest.java
+++ b/tests/unit/java/android/net/NetworkStatsCollectionTest.java
@@ -38,13 +38,11 @@
import static org.junit.Assert.fail;
import android.content.res.Resources;
-import android.net.NetworkStatsCollection.Key;
import android.os.Process;
import android.os.UserHandle;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
-import android.util.ArrayMap;
import android.util.RecurrenceRule;
import androidx.test.InstrumentationRegistry;
@@ -75,7 +73,6 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
/**
* Tests for {@link NetworkStatsCollection}.
@@ -87,6 +84,7 @@
private static final String TEST_FILE = "test.bin";
private static final String TEST_IMSI = "310260000000000";
+ private static final int TEST_SUBID = 1;
private static final long TIME_A = 1326088800000L; // UTC: Monday 9th January 2012 06:00:00 AM
private static final long TIME_B = 1326110400000L; // UTC: Monday 9th January 2012 12:00:00 PM
@@ -213,7 +211,7 @@
final NetworkStats.Entry entry = new NetworkStats.Entry();
final NetworkIdentitySet identSet = new NetworkIdentitySet();
identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
- TEST_IMSI, null, false, true, true, OEM_NONE));
+ TEST_IMSI, null, false, true, true, OEM_NONE, TEST_SUBID));
int myUid = Process.myUid();
int otherUidInSameUser = Process.myUid() + 1;
@@ -475,7 +473,7 @@
final NetworkStatsCollection large = new NetworkStatsCollection(HOUR_IN_MILLIS);
final NetworkIdentitySet ident = new NetworkIdentitySet();
ident.add(new NetworkIdentity(ConnectivityManager.TYPE_MOBILE, -1, TEST_IMSI, null,
- false, true, true, OEM_NONE));
+ false, true, true, OEM_NONE, TEST_SUBID));
large.recordData(ident, UID_ALL, SET_ALL, TAG_NONE, TIME_A, TIME_B,
new NetworkStats.Entry(12_730_893_164L, 1, 0, 0, 0));
@@ -533,52 +531,6 @@
assertThrows(ArithmeticException.class, () -> multiplySafeByRational(30, 3, 0));
}
- @Test
- public void testBuilder() {
- final Map<Key, NetworkStatsHistory> expectedEntries = new ArrayMap<>();
- final NetworkStats.Entry entry = new NetworkStats.Entry();
- final NetworkIdentitySet ident = new NetworkIdentitySet();
- final Key key1 = new Key(ident, 0, 0, 0);
- final Key key2 = new Key(ident, 1, 0, 0);
- final long bucketDuration = 10;
-
- final NetworkStatsHistory.Entry entry1 = new NetworkStatsHistory.Entry(10, 10, 40,
- 4, 50, 5, 60);
- final NetworkStatsHistory.Entry entry2 = new NetworkStatsHistory.Entry(30, 10, 3,
- 41, 7, 1, 0);
-
- NetworkStatsHistory history1 = new NetworkStatsHistory.Builder(10, 5)
- .addEntry(entry1)
- .addEntry(entry2)
- .build();
-
- NetworkStatsHistory history2 = new NetworkStatsHistory(10, 5);
-
- NetworkStatsCollection actualCollection = new NetworkStatsCollection.Builder(bucketDuration)
- .addEntry(key1, history1)
- .addEntry(key2, history2)
- .build();
-
- // The builder will omit any entry with empty history. Thus, history2
- // is not expected in the result collection.
- expectedEntries.put(key1, history1);
-
- final Map<Key, NetworkStatsHistory> actualEntries = actualCollection.getEntries();
-
- assertEquals(expectedEntries.size(), actualEntries.size());
- for (Key expectedKey : expectedEntries.keySet()) {
- final NetworkStatsHistory expectedHistory = expectedEntries.get(expectedKey);
-
- final NetworkStatsHistory actualHistory = actualEntries.get(expectedKey);
- assertNotNull(actualHistory);
-
- assertEquals(expectedHistory.getEntries(), actualHistory.getEntries());
-
- actualEntries.remove(expectedKey);
- }
- assertEquals(0, actualEntries.size());
- }
-
/**
* Copy a {@link Resources#openRawResource(int)} into {@link File} for
* testing purposes.
diff --git a/tests/unit/java/android/net/NetworkStatsHistoryTest.java b/tests/unit/java/android/net/NetworkStatsHistoryTest.java
index c170605..c5f8c00 100644
--- a/tests/unit/java/android/net/NetworkStatsHistoryTest.java
+++ b/tests/unit/java/android/net/NetworkStatsHistoryTest.java
@@ -56,7 +56,6 @@
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
-import java.util.List;
import java.util.Random;
@RunWith(DevSdkIgnoreRunner.class)
@@ -533,40 +532,6 @@
assertEquals(512L + 4096L, stats.getTotalBytes());
}
- @Test
- public void testBuilder() {
- final NetworkStatsHistory.Entry entry1 = new NetworkStatsHistory.Entry(10, 30, 40,
- 4, 50, 5, 60);
- final NetworkStatsHistory.Entry entry2 = new NetworkStatsHistory.Entry(30, 15, 3,
- 41, 7, 1, 0);
- final NetworkStatsHistory.Entry entry3 = new NetworkStatsHistory.Entry(7, 301, 11,
- 14, 31, 2, 80);
-
- final NetworkStatsHistory statsEmpty = new NetworkStatsHistory
- .Builder(HOUR_IN_MILLIS, 10).build();
- assertEquals(0, statsEmpty.getEntries().size());
- assertEquals(HOUR_IN_MILLIS, statsEmpty.getBucketDuration());
-
- NetworkStatsHistory statsSingle = new NetworkStatsHistory
- .Builder(HOUR_IN_MILLIS, 8)
- .addEntry(entry1)
- .build();
- assertEquals(1, statsSingle.getEntries().size());
- assertEquals(HOUR_IN_MILLIS, statsSingle.getBucketDuration());
- assertEquals(entry1, statsSingle.getEntries().get(0));
-
- NetworkStatsHistory statsMultiple = new NetworkStatsHistory
- .Builder(SECOND_IN_MILLIS, 0)
- .addEntry(entry1).addEntry(entry2).addEntry(entry3)
- .build();
- final List<NetworkStatsHistory.Entry> entries = statsMultiple.getEntries();
- assertEquals(3, entries.size());
- assertEquals(SECOND_IN_MILLIS, statsMultiple.getBucketDuration());
- assertEquals(entry1, entries.get(0));
- assertEquals(entry2, entries.get(1));
- assertEquals(entry3, entries.get(2));
- }
-
private static void assertIndexBeforeAfter(
NetworkStatsHistory stats, int before, int after, long time) {
assertEquals("unexpected before", before, stats.getIndexBefore(time));
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index 453612f..abd1825 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -29,12 +29,8 @@
import android.net.NetworkStats.METERED_NO
import android.net.NetworkStats.METERED_YES
import android.net.NetworkStats.ROAMING_ALL
-import android.net.NetworkTemplate.MATCH_BLUETOOTH
-import android.net.NetworkTemplate.MATCH_CARRIER
-import android.net.NetworkTemplate.MATCH_ETHERNET
import android.net.NetworkTemplate.MATCH_MOBILE
import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
-import android.net.NetworkTemplate.MATCH_PROXY
import android.net.NetworkTemplate.MATCH_WIFI
import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
import android.net.NetworkTemplate.NETWORK_TYPE_ALL
@@ -52,11 +48,9 @@
import android.net.wifi.WifiInfo
import android.os.Build
import android.telephony.TelephonyManager
-import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_ALL
import com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
-import com.android.testutils.SC_V2
import com.android.testutils.assertParcelSane
import org.junit.Before
import org.junit.Test
@@ -65,7 +59,6 @@
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
@@ -555,140 +548,4 @@
it.assertMatches(identMobileImsi3)
}
}
-
- @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
- @Test
- fun testBuilderMatchRules() {
- // Verify unknown match rules cannot construct templates.
- listOf(Integer.MIN_VALUE, -1, Integer.MAX_VALUE).forEach {
- assertFailsWith<IllegalArgumentException> {
- NetworkTemplate.Builder(it).build()
- }
- }
-
- // Verify hidden match rules cannot construct templates.
- listOf(MATCH_WIFI_WILDCARD, MATCH_MOBILE_WILDCARD, MATCH_PROXY).forEach {
- assertFailsWith<IllegalArgumentException> {
- NetworkTemplate.Builder(it).build()
- }
- }
-
- // Verify template which matches metered cellular and carrier networks with
- // the given IMSI. See buildTemplateMobileAll and buildTemplateCarrierMetered.
- listOf(MATCH_MOBILE, MATCH_CARRIER).forEach { matchRule ->
- NetworkTemplate.Builder(matchRule).setSubscriberIds(setOf(TEST_IMSI1))
- .setMeteredness(METERED_YES).build().let {
- val expectedTemplate = NetworkTemplate(matchRule, TEST_IMSI1,
- arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
- ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
- assertEquals(expectedTemplate, it)
- }
- }
-
- // Verify carrier template cannot be created without IMSI.
- assertFailsWith<IllegalArgumentException> {
- NetworkTemplate.Builder(MATCH_CARRIER).build()
- }
-
- // Verify template which matches metered cellular networks,
- // regardless of IMSI. See buildTemplateMobileWildcard.
- NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build().let {
- val expectedTemplate = NetworkTemplate(MATCH_MOBILE_WILDCARD, null /*subscriberId*/,
- null /*subscriberIds*/, arrayOf<String>(),
- METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
- assertEquals(expectedTemplate, it)
- }
-
- // Verify template which matches metered cellular networks and ratType.
- // See NetworkTemplate#buildTemplateMobileWithRatType.
- NetworkTemplate.Builder(MATCH_MOBILE).setSubscriberIds(setOf(TEST_IMSI1))
- .setMeteredness(METERED_YES).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
- .build().let {
- val expectedTemplate = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1,
- arrayOf(TEST_IMSI1), arrayOf<String>(), METERED_YES,
- ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_UMTS,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
- assertEquals(expectedTemplate, it)
- }
-
- // Verify template which matches all wifi networks,
- // regardless of Wifi Network Key. See buildTemplateWifiWildcard and buildTemplateWifi.
- NetworkTemplate.Builder(MATCH_WIFI).build().let {
- val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
- null /*subscriberIds*/, arrayOf<String>(),
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
- assertEquals(expectedTemplate, it)
- }
-
- // Verify template which matches wifi networks with the given Wifi Network Key.
- // See buildTemplateWifi(wifiNetworkKey).
- NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
- val expectedTemplate = NetworkTemplate(MATCH_WIFI, null /*subscriberId*/,
- null /*subscriberIds*/, arrayOf(TEST_WIFI_KEY1),
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
- assertEquals(expectedTemplate, it)
- }
-
- // Verify template which matches all wifi networks with the
- // given Wifi Network Key, and IMSI. See buildTemplateWifi(wifiNetworkKey, subscriberId).
- NetworkTemplate.Builder(MATCH_WIFI).setSubscriberIds(setOf(TEST_IMSI1))
- .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build().let {
- val expectedTemplate = NetworkTemplate(MATCH_WIFI, TEST_IMSI1,
- arrayOf(TEST_IMSI1), arrayOf(TEST_WIFI_KEY1),
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
- assertEquals(expectedTemplate, it)
- }
-
- // Verify template which matches ethernet and bluetooth networks.
- // See buildTemplateEthernet and buildTemplateBluetooth.
- listOf(MATCH_ETHERNET, MATCH_BLUETOOTH).forEach { matchRule ->
- NetworkTemplate.Builder(matchRule).build().let {
- val expectedTemplate = NetworkTemplate(matchRule, null /*subscriberId*/,
- null /*subscriberIds*/, arrayOf<String>(),
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
- assertEquals(expectedTemplate, it)
- }
- }
- }
-
- @DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
- @Test
- fun testBuilderWifiNetworkKeys() {
- // Verify template builder which generates same template with the given different
- // sequence keys.
- NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
- setOf(TEST_WIFI_KEY1, TEST_WIFI_KEY2)).build().let {
- val expectedTemplate = NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(
- setOf(TEST_WIFI_KEY2, TEST_WIFI_KEY1)).build()
- assertEquals(expectedTemplate, it)
- }
-
- // Verify template which matches non-wifi networks with the given key is invalid.
- listOf(MATCH_MOBILE, MATCH_CARRIER, MATCH_ETHERNET, MATCH_BLUETOOTH, -1,
- Integer.MAX_VALUE).forEach { matchRule ->
- assertFailsWith<IllegalArgumentException> {
- NetworkTemplate.Builder(matchRule).setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
- }
- }
-
- // Verify template which matches wifi networks with the given null key is invalid.
- assertFailsWith<IllegalArgumentException> {
- NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf(null)).build()
- }
-
- // Verify template which matches wifi wildcard with the given empty key set.
- NetworkTemplate.Builder(MATCH_WIFI).setWifiNetworkKeys(setOf<String>()).build().let {
- val expectedTemplate = NetworkTemplate(MATCH_WIFI_WILDCARD, null /*subscriberId*/,
- arrayOf<String>() /*subscriberIds*/, arrayOf<String>(),
- METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
- OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_ALL)
- assertEquals(expectedTemplate, it)
- }
- }
}
diff --git a/tests/unit/java/android/net/netstats/NetworkStatsDataMigrationUtilsTest.kt b/tests/unit/java/android/net/netstats/NetworkStatsDataMigrationUtilsTest.kt
index e4943ea..743d39e 100644
--- a/tests/unit/java/android/net/netstats/NetworkStatsDataMigrationUtilsTest.kt
+++ b/tests/unit/java/android/net/netstats/NetworkStatsDataMigrationUtilsTest.kt
@@ -46,7 +46,7 @@
@Test
fun testReadPlatformCollection() {
- // Verify the method throws for wrong file version.
+ // Verify the method throws for wrong file format.
assertFailsWith<ProtocolException> {
NetworkStatsDataMigrationUtils.readPlatformCollection(
NetworkStatsCollection.Builder(BUCKET_DURATION_MS),
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 16b3d5a..8ec6257 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -573,6 +573,12 @@
// is "<permission name>,<pid>,<uid>". PID+UID permissons have priority over generic ones.
private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
+ private void mockStringResource(int resId) {
+ doAnswer((inv) -> {
+ return "Mock string resource ID=" + inv.getArgument(0);
+ }).when(mInternalResources).getString(resId);
+ }
+
MockContext(Context base, ContentProvider settingsProvider) {
super(base);
@@ -585,6 +591,18 @@
}).when(mInternalResources)
.getStringArray(com.android.internal.R.array.networkAttributes);
+ final int[] stringResourcesToMock = new int[] {
+ com.android.internal.R.string.config_customVpnAlwaysOnDisconnectedDialogComponent,
+ com.android.internal.R.string.vpn_lockdown_config,
+ com.android.internal.R.string.vpn_lockdown_connected,
+ com.android.internal.R.string.vpn_lockdown_connecting,
+ com.android.internal.R.string.vpn_lockdown_disconnected,
+ com.android.internal.R.string.vpn_lockdown_error,
+ };
+ for (int resId : stringResourcesToMock) {
+ mockStringResource(resId);
+ }
+
mContentResolver = new MockContentResolver();
mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider);
}
@@ -907,6 +925,7 @@
return null;
};
+ doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any());
doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnectedParcel(any());
doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
diff --git a/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt b/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
index 785153a..e7f6245 100644
--- a/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
@@ -26,6 +26,8 @@
import com.android.server.connectivity.FullScore.MAX_CS_MANAGED_POLICY
import com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED
import com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED
+import com.android.server.connectivity.FullScore.POLICY_IS_DESTROYED
+import com.android.server.connectivity.FullScore.POLICY_IS_UNMETERED
import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED
import com.android.server.connectivity.FullScore.POLICY_IS_VPN
import com.android.testutils.DevSdkIgnoreRule
@@ -47,7 +49,8 @@
validated: Boolean = false,
vpn: Boolean = false,
onceChosen: Boolean = false,
- acceptUnvalidated: Boolean = false
+ acceptUnvalidated: Boolean = false,
+ destroyed: Boolean = false
): FullScore {
val nac = NetworkAgentConfig.Builder().apply {
setUnvalidatedConnectivityAcceptable(acceptUnvalidated)
@@ -57,7 +60,7 @@
if (vpn) addTransportType(NetworkCapabilities.TRANSPORT_VPN)
if (validated) addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}.build()
- return mixInScore(nc, nac, validated, false /* yieldToBadWifi */)
+ return mixInScore(nc, nac, validated, false /* yieldToBadWifi */, destroyed)
}
@Test
@@ -101,6 +104,7 @@
assertFailsWith<IllegalArgumentException> {
FullScore.policyNameOf(MAX_CS_MANAGED_POLICY + 1)
}
+ assertEquals("IS_UNMETERED", FullScore.policyNameOf(POLICY_IS_UNMETERED))
}
fun getAllPolicies() = Regex("POLICY_.*").let { nameRegex ->
@@ -118,6 +122,7 @@
assertTrue(ns.withPolicies(vpn = true).hasPolicy(POLICY_IS_VPN))
assertTrue(ns.withPolicies(onceChosen = true).hasPolicy(POLICY_EVER_USER_SELECTED))
assertTrue(ns.withPolicies(acceptUnvalidated = true).hasPolicy(POLICY_ACCEPT_UNVALIDATED))
+ assertTrue(ns.withPolicies(destroyed = true).hasPolicy(POLICY_IS_DESTROYED))
}
@Test
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
index 66dcf6d..5f9d1ff 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -36,6 +36,7 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import android.content.Context;
import android.net.DataUsageRequest;
import android.net.NetworkIdentity;
import android.net.NetworkIdentitySet;
@@ -78,6 +79,7 @@
private static final String IMSI_1 = "310004";
private static final String IMSI_2 = "310260";
+ private static final int SUBID_1 = 1;
private static final String TEST_SSID = "AndroidAP";
private static NetworkTemplate sTemplateWifi = buildTemplateWifiWildcard();
@@ -101,6 +103,7 @@
@Mock private IBinder mUsageCallbackBinder;
private TestableUsageCallback mUsageCallback;
+ @Mock private Context mContext;
@Before
public void setUp() throws Exception {
@@ -127,14 +130,14 @@
final DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdTooLowBytes);
- final DataUsageRequest requestByApp = mStatsObservers.register(inputRequest, mUsageCallback,
- UID_RED, NetworkStatsAccess.Level.DEVICE);
+ final DataUsageRequest requestByApp = mStatsObservers.register(mContext, inputRequest,
+ mUsageCallback, UID_RED, NetworkStatsAccess.Level.DEVICE);
assertTrue(requestByApp.requestId > 0);
assertTrue(Objects.equals(sTemplateWifi, requestByApp.template));
- assertEquals(THRESHOLD_BYTES, requestByApp.thresholdInBytes);
+ assertEquals(thresholdTooLowBytes, requestByApp.thresholdInBytes);
// Verify the threshold requested by system uid won't be overridden.
- final DataUsageRequest requestBySystem = mStatsObservers.register(inputRequest,
+ final DataUsageRequest requestBySystem = mStatsObservers.register(mContext, inputRequest,
mUsageCallback, Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(requestBySystem.requestId > 0);
assertTrue(Objects.equals(sTemplateWifi, requestBySystem.template));
@@ -147,7 +150,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, highThresholdBytes);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateWifi, request.template));
@@ -159,13 +162,13 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, THRESHOLD_BYTES);
- DataUsageRequest request1 = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request1 = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(request1.requestId > 0);
assertTrue(Objects.equals(sTemplateWifi, request1.template));
assertEquals(THRESHOLD_BYTES, request1.thresholdInBytes);
- DataUsageRequest request2 = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request2 = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(request2.requestId > request1.requestId);
assertTrue(Objects.equals(sTemplateWifi, request2.template));
@@ -185,7 +188,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -205,7 +208,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
UID_RED, NetworkStatsAccess.Level.DEVICE);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -224,7 +227,7 @@
identSet.add(new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
IMSI_1, null /* networkId */, false /* roaming */, true /* metered */,
- true /* defaultNetwork */, OEM_NONE));
+ true /* defaultNetwork */, OEM_NONE, SUBID_1));
return identSet;
}
@@ -233,7 +236,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -257,7 +260,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -287,7 +290,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
Process.SYSTEM_UID, NetworkStatsAccess.Level.DEVICE);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -318,7 +321,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
UID_RED, NetworkStatsAccess.Level.DEFAULT);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -351,7 +354,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
UID_BLUE, NetworkStatsAccess.Level.DEFAULT);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -383,7 +386,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
UID_BLUE, NetworkStatsAccess.Level.USER);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
@@ -416,7 +419,7 @@
DataUsageRequest inputRequest = new DataUsageRequest(
DataUsageRequest.REQUEST_ID_UNSET, sTemplateImsi1, THRESHOLD_BYTES);
- DataUsageRequest request = mStatsObservers.register(inputRequest, mUsageCallback,
+ DataUsageRequest request = mStatsObservers.register(mContext, inputRequest, mUsageCallback,
UID_RED, NetworkStatsAccess.Level.USER);
assertTrue(request.requestId > 0);
assertTrue(Objects.equals(sTemplateImsi1, request.template));
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 76c0c38..aa4e4bb 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -63,8 +63,10 @@
import static com.android.net.module.util.NetworkStatsUtils.SUBSCRIBER_ID_MATCH_RULE_EXACT;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
@@ -77,6 +79,7 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -101,13 +104,13 @@
import android.net.UnderlyingNetworkInfo;
import android.net.netstats.provider.INetworkStatsProviderCallback;
import android.net.wifi.WifiInfo;
-import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.SimpleClock;
import android.provider.Settings;
+import android.system.ErrnoException;
import android.telephony.TelephonyManager;
import androidx.annotation.Nullable;
@@ -125,6 +128,7 @@
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import com.android.testutils.HandlerUtils;
+import com.android.testutils.TestBpfMap;
import com.android.testutils.TestableNetworkStatsProviderBinder;
import libcore.testing.io.TestIoUtils;
@@ -143,6 +147,7 @@
import java.time.ZoneOffset;
import java.util.Objects;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* Tests for {@link NetworkStatsService}.
@@ -152,7 +157,8 @@
*/
@RunWith(DevSdkIgnoreRunner.class)
@SmallTest
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+// NetworkStatsService is not updatable before T, so tests do not need to be backwards compatible
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
private static final String TAG = "NetworkStatsServiceTest";
@@ -197,8 +203,16 @@
private HandlerThread mHandlerThread;
@Mock
private LocationPermissionChecker mLocationPermissionChecker;
- private @Mock IBpfMap<U32, U8> mUidCounterSetMap;
- private @Mock NetworkStatsService.TagStatsDeleter mTagStatsDeleter;
+ private TestBpfMap<U32, U8> mUidCounterSetMap = spy(new TestBpfMap<>(U32.class, U8.class));
+
+ private TestBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap = new TestBpfMap<>(
+ CookieTagMapKey.class, CookieTagMapValue.class);
+ private TestBpfMap<StatsMapKey, StatsMapValue> mStatsMapA = new TestBpfMap<>(StatsMapKey.class,
+ StatsMapValue.class);
+ private TestBpfMap<StatsMapKey, StatsMapValue> mStatsMapB = new TestBpfMap<>(StatsMapKey.class,
+ StatsMapValue.class);
+ private TestBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap = new TestBpfMap<>(
+ UidStatsMapKey.class, StatsMapValue.class);
private NetworkStatsService mService;
private INetworkStatsSession mSession;
@@ -361,8 +375,23 @@
}
@Override
- public NetworkStatsService.TagStatsDeleter getTagStatsDeleter() {
- return mTagStatsDeleter;
+ public IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() {
+ return mCookieTagMap;
+ }
+
+ @Override
+ public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapA() {
+ return mStatsMapA;
+ }
+
+ @Override
+ public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapB() {
+ return mStatsMapB;
+ }
+
+ @Override
+ public IBpfMap<UidStatsMapKey, StatsMapValue> getAppUidStatsMap() {
+ return mAppUidStatsMap;
}
};
}
@@ -702,10 +731,8 @@
final Intent intent = new Intent(ACTION_UID_REMOVED);
intent.putExtra(EXTRA_UID, UID_BLUE);
mServiceContext.sendBroadcast(intent);
- verify(mTagStatsDeleter).deleteTagData(UID_BLUE);
intent.putExtra(EXTRA_UID, UID_RED);
mServiceContext.sendBroadcast(intent);
- verify(mTagStatsDeleter).deleteTagData(UID_RED);
// existing uid and total should remain unchanged; but removed UID
// should be gone completely.
@@ -1905,4 +1932,70 @@
private void waitForIdle() {
HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
}
+
+ private boolean cookieTagMapContainsUid(int uid) throws ErrnoException {
+ final AtomicBoolean found = new AtomicBoolean();
+ mCookieTagMap.forEach((k, v) -> {
+ if (v.uid == uid) {
+ found.set(true);
+ }
+ });
+ return found.get();
+ }
+
+ private static <K extends StatsMapKey, V extends StatsMapValue> boolean statsMapContainsUid(
+ TestBpfMap<K, V> map, int uid) throws ErrnoException {
+ final AtomicBoolean found = new AtomicBoolean();
+ map.forEach((k, v) -> {
+ if (k.uid == uid) {
+ found.set(true);
+ }
+ });
+ return found.get();
+ }
+
+ private void initBpfMapsWithTagData(int uid) throws ErrnoException {
+ // key needs to be unique, use some offset from uid.
+ mCookieTagMap.insertEntry(new CookieTagMapKey(1000 + uid), new CookieTagMapValue(uid, 1));
+ mCookieTagMap.insertEntry(new CookieTagMapKey(2000 + uid), new CookieTagMapValue(uid, 2));
+
+ mStatsMapA.insertEntry(new StatsMapKey(uid, 1, 0, 10), new StatsMapValue(5, 5000, 3, 3000));
+ mStatsMapA.insertEntry(new StatsMapKey(uid, 2, 0, 10), new StatsMapValue(5, 5000, 3, 3000));
+
+ mStatsMapB.insertEntry(new StatsMapKey(uid, 1, 0, 10), new StatsMapValue(0, 0, 0, 0));
+
+ mAppUidStatsMap.insertEntry(new UidStatsMapKey(uid), new StatsMapValue(10, 10000, 6, 6000));
+
+ mUidCounterSetMap.insertEntry(new U32(uid), new U8((short) 1));
+
+ assertTrue(cookieTagMapContainsUid(uid));
+ assertTrue(statsMapContainsUid(mStatsMapA, uid));
+ assertTrue(statsMapContainsUid(mStatsMapB, uid));
+ assertTrue(mAppUidStatsMap.containsKey(new UidStatsMapKey(uid)));
+ assertTrue(mUidCounterSetMap.containsKey(new U32(uid)));
+ }
+
+ @Test
+ public void testRemovingUidRemovesTagDataForUid() throws ErrnoException {
+ initBpfMapsWithTagData(UID_BLUE);
+ initBpfMapsWithTagData(UID_RED);
+
+ final Intent intent = new Intent(ACTION_UID_REMOVED);
+ intent.putExtra(EXTRA_UID, UID_BLUE);
+ mServiceContext.sendBroadcast(intent);
+
+ // assert that all UID_BLUE related tag data has been removed from the maps.
+ assertFalse(cookieTagMapContainsUid(UID_BLUE));
+ assertFalse(statsMapContainsUid(mStatsMapA, UID_BLUE));
+ assertFalse(statsMapContainsUid(mStatsMapB, UID_BLUE));
+ assertFalse(mAppUidStatsMap.containsKey(new UidStatsMapKey(UID_BLUE)));
+ assertFalse(mUidCounterSetMap.containsKey(new U32(UID_BLUE)));
+
+ // assert that UID_RED related tag data is still in the maps.
+ assertTrue(cookieTagMapContainsUid(UID_RED));
+ assertTrue(statsMapContainsUid(mStatsMapA, UID_RED));
+ assertTrue(statsMapContainsUid(mStatsMapB, UID_RED));
+ assertTrue(mAppUidStatsMap.containsKey(new UidStatsMapKey(UID_RED)));
+ assertTrue(mUidCounterSetMap.containsKey(new U32(UID_RED)));
+ }
}