From 1c5f5b527097a3f512788d7107970f972eee23b8 Mon Sep 17 00:00:00 2001 From: Junyu Lai Date: Wed, 21 May 2025 20:18:37 +0800 Subject: [PATCH] Add kill switch for storing transport types In case there is a bug after rolling out transport types support in the NetworkIdentity. Add a kill switch to stop writing transport types to mitigate the impact if any. Flag: EXEMPT the change is the kill switch Test: atest ConnectivityCoverageTests --test-filter \ 'NetworkIdentity*' --update-device Test: atest ConnectivityCoverageTests --test-filter \ 'NetworkStats*' --update-device Test: atest ConnectivityBenchmarkTests Test: atest FrameworksNetIntegrationTests:com.android.server.net.integrationtests.NetworkStatsIntegrationTest Test: Manual: 1. Download files 2. adb shell device_config put tethering store_transport_types -1 3. reboot and check Data Usage Settings page. Bug: 419123367 Change-Id: I52791f6fe5207021748641cf0719055533b5d511 --- .../src/android/net/NetworkIdentitySet.java | 18 +++++-- .../android/net/NetworkStatsCollection.java | 26 +++++----- .../server/net/NetworkStatsRecorder.java | 38 +++++++++----- .../server/net/NetworkStatsService.java | 15 +++++- .../benchmarktests/NetworkStatsTest.kt | 17 ++++-- .../android/net/NetworkIdentitySetTest.kt | 52 +++++++++++++++---- .../net/NetworkStatsCollectionTest.java | 36 ++++++++----- .../android/net/NetworkStatsRecorderTest.java | 14 +++-- .../server/net/NetworkStatsServiceTest.java | 8 ++- 9 files changed, 163 insertions(+), 61 deletions(-) diff --git a/framework-t/src/android/net/NetworkIdentitySet.java b/framework-t/src/android/net/NetworkIdentitySet.java index a0b3d3dec2..9bc278e1a3 100644 --- a/framework-t/src/android/net/NetworkIdentitySet.java +++ b/framework-t/src/android/net/NetworkIdentitySet.java @@ -50,8 +50,10 @@ public class NetworkIdentitySet extends HashSet { private static final int VERSION_ADD_METERED = 4; private static final int VERSION_ADD_DEFAULT_NETWORK = 5; private static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6; - private static final int VERSION_ADD_SUB_ID = 7; - private static final int VERSION_ADD_TRANSPORT_TYPES = 8; + @VisibleForTesting + public static final int VERSION_ADD_SUB_ID = 7; + @VisibleForTesting + public static final int VERSION_ADD_TRANSPORT_TYPES = 8; /** * Construct a {@link NetworkIdentitySet} object. @@ -144,8 +146,12 @@ public class NetworkIdentitySet extends HashSet { * Method to serialize this object into a {@code DataOutput}. * @hide */ - public void writeToStream(DataOutput out) throws IOException { - out.writeInt(VERSION_ADD_TRANSPORT_TYPES); + public void writeToStream(DataOutput out, boolean storeTransportTypes) throws IOException { + if (storeTransportTypes) { + out.writeInt(VERSION_ADD_TRANSPORT_TYPES); + } else { + out.writeInt(VERSION_ADD_SUB_ID); + } out.writeInt(size()); for (NetworkIdentity ident : this) { out.writeInt(ident.getType()); @@ -157,7 +163,9 @@ public class NetworkIdentitySet extends HashSet { out.writeBoolean(ident.isDefaultNetwork()); out.writeInt(ident.getOemManaged()); out.writeInt(ident.getSubId()); - out.writeLong(BitUtils.packBits(toIntArray(ident.getTransportTypes()))); + if (storeTransportTypes) { + out.writeLong(BitUtils.packBits(toIntArray(ident.getTransportTypes()))); + } } } diff --git a/framework-t/src/android/net/NetworkStatsCollection.java b/framework-t/src/android/net/NetworkStatsCollection.java index 934b4c6a0e..9febbcb535 100644 --- a/framework-t/src/android/net/NetworkStatsCollection.java +++ b/framework-t/src/android/net/NetworkStatsCollection.java @@ -118,27 +118,21 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W private long mTotalBytes; private boolean mDirty; private final boolean mUseFastDataInput; - - /** - * Construct a {@link NetworkStatsCollection} object. - * - * @param bucketDurationMillis duration of the buckets in this object, in milliseconds. - * @hide - */ - public NetworkStatsCollection(long bucketDurationMillis) { - this(bucketDurationMillis, false /* useFastDataInput */); - } + private final boolean mStoreTransportTypes; /** * Construct a {@link NetworkStatsCollection} object. * * @param bucketDurationMillis duration of the buckets in this object, in milliseconds. * @param useFastDataInput true if using {@link FastDataInput} is preferred. Otherwise, false. + * @param storeTransportTypes true if storing transport types is supported. Otherwise, false. * @hide */ - public NetworkStatsCollection(long bucketDurationMillis, boolean useFastDataInput) { + public NetworkStatsCollection(long bucketDurationMillis, boolean useFastDataInput, + boolean storeTransportTypes) { mBucketDurationMillis = bucketDurationMillis; mUseFastDataInput = useFastDataInput; + mStoreTransportTypes = storeTransportTypes; reset(); } @@ -563,7 +557,7 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W out.writeInt(keysByIdent.size()); for (NetworkIdentitySet ident : keysByIdent.keySet()) { final ArrayList keys = keysByIdent.get(ident); - ident.writeToStream(out); + ident.writeToStream(out, mStoreTransportTypes); out.writeInt(keys.size()); for (Key key : keys) { @@ -935,8 +929,14 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W */ @NonNull public NetworkStatsCollection build() { + // If this object is OEM-created, especially for data migration, + // `storeTransportTypes` is set to `false` because older data lacks transport types. + // The file will be rewritten with transport types later if the feature is enabled. + // For OEM objects not used by the importer, this flag remains `false` as + // transport types aren't applicable yet, indicating the new feature isn't available. final NetworkStatsCollection collection = - new NetworkStatsCollection(mBucketDurationMillis); + new NetworkStatsCollection(mBucketDurationMillis, false /* useFastDataInput */, + false /* storeTransportTypes */); for (int i = 0; i < mEntries.size(); i++) { collection.recordHistory(mEntries.keyAt(i), mEntries.valueAt(i)); } diff --git a/service-t/src/com/android/server/net/NetworkStatsRecorder.java b/service-t/src/com/android/server/net/NetworkStatsRecorder.java index 8ee8591a4f..966964afa8 100644 --- a/service-t/src/com/android/server/net/NetworkStatsRecorder.java +++ b/service-t/src/com/android/server/net/NetworkStatsRecorder.java @@ -84,6 +84,7 @@ public class NetworkStatsRecorder { private final boolean mOnlyTags; private final boolean mWipeOnError; private final boolean mUseFastDataInput; + private final boolean mStoreTransportTypes; private long mPersistThresholdBytes = 2 * MB_IN_BYTES; private NetworkStats mLastSnapshot; @@ -113,9 +114,14 @@ public class NetworkStatsRecorder { mOnlyTags = false; mWipeOnError = true; mUseFastDataInput = false; + mStoreTransportTypes = true; mPending = null; - mSinceBoot = new NetworkStatsCollection(mBucketDuration); + // This is only used to track usage inside the observer, which doesn't read/write + // from/to persistent files. It is guaranteed that the file won't be written + // because the rotator is null. + mSinceBoot = new NetworkStatsCollection(mBucketDuration, mUseFastDataInput, + mStoreTransportTypes); mPendingRewriter = null; mStatsDir = null; @@ -126,7 +132,8 @@ public class NetworkStatsRecorder { */ public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver observer, DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags, - boolean wipeOnError, boolean useFastDataInput, @Nullable File statsDir) { + boolean wipeOnError, boolean useFastDataInput, boolean storeTransportTypes, + @Nullable File statsDir) { mRotator = Objects.requireNonNull(rotator, "missing FileRotator"); mObserver = Objects.requireNonNull(observer, "missing NonMonotonicObserver"); mDropBox = Objects.requireNonNull(dropBox, "missing DropBoxManager"); @@ -136,9 +143,12 @@ public class NetworkStatsRecorder { mOnlyTags = onlyTags; mWipeOnError = wipeOnError; mUseFastDataInput = useFastDataInput; + mStoreTransportTypes = storeTransportTypes; - mPending = new NetworkStatsCollection(bucketDuration); - mSinceBoot = new NetworkStatsCollection(bucketDuration); + mPending = new NetworkStatsCollection(bucketDuration, mUseFastDataInput, + mStoreTransportTypes); + mSinceBoot = new NetworkStatsCollection(bucketDuration, mUseFastDataInput, + mStoreTransportTypes); mPendingRewriter = new CombiningRewriter(mPending); mStatsDir = statsDir; @@ -220,7 +230,8 @@ public class NetworkStatsRecorder { + " useFastDataInput: " + mUseFastDataInput); } final NetworkStatsCollection res = - new NetworkStatsCollection(mBucketDuration, mUseFastDataInput); + new NetworkStatsCollection(mBucketDuration, mUseFastDataInput, + mStoreTransportTypes); try { mRotator.readMatching(res, start, end); res.recordCollection(mPending); @@ -353,7 +364,9 @@ public class NetworkStatsRecorder { if (mRotator != null) { try { // Rewrite all persisted data to migrate UID stats - mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uids)); + final NetworkStatsCollection temp = new NetworkStatsCollection(mBucketDuration, + mUseFastDataInput, mStoreTransportTypes); + mRotator.rewriteAll(new RemoveUidRewriter(temp, uids)); } catch (IOException e) { Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e); recoverAndDeleteData(); @@ -422,8 +435,8 @@ public class NetworkStatsRecorder { private final NetworkStatsCollection mTemp; private final int[] mUids; - public RemoveUidRewriter(long bucketDuration, int[] uids) { - mTemp = new NetworkStatsCollection(bucketDuration); + public RemoveUidRewriter(@NonNull NetworkStatsCollection temp, int[] uids) { + mTemp = temp; mUids = uids; } @@ -475,8 +488,8 @@ public class NetworkStatsRecorder { private final NetworkStatsCollection mTemp; private final long mCutoffMills; - public RemoveDataBeforeRewriter(long bucketDuration, long cutoffMills) { - mTemp = new NetworkStatsCollection(bucketDuration); + public RemoveDataBeforeRewriter(@NonNull NetworkStatsCollection temp, long cutoffMills) { + mTemp = temp; mCutoffMills = cutoffMills; } @@ -509,8 +522,9 @@ public class NetworkStatsRecorder { public void removeDataBefore(long cutoffMillis) throws IOException { if (mRotator != null) { try { - mRotator.rewriteAll(new RemoveDataBeforeRewriter( - mBucketDuration, cutoffMillis)); + final NetworkStatsCollection temp = new NetworkStatsCollection(mBucketDuration, + mUseFastDataInput, mStoreTransportTypes); + mRotator.rewriteAll(new RemoveDataBeforeRewriter(temp, cutoffMillis)); } catch (IOException e) { Log.wtf(TAG, "problem importing netstats", e); recoverAndDeleteData(); diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java index 01ff34d8b4..2f4b67eee4 100644 --- a/service-t/src/com/android/server/net/NetworkStatsService.java +++ b/service-t/src/com/android/server/net/NetworkStatsService.java @@ -499,6 +499,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @VisibleForTesting public static final String TRAFFICSTATS_CLIENT_RATE_LIMIT_CACHE_ENABLED_FLAG = "trafficstats_client_rate_limit_cache_enabled_flag"; + @VisibleForTesting + public static final String STORE_TRANSPORT_TYPES = "store_transport_types"; static final String TRAFFICSTATS_SERVICE_RATE_LIMIT_CACHE_ENABLED_FLAG = "trafficstats_rate_limit_cache_enabled_flag"; static final String BROADCAST_NETWORK_STATS_UPDATED_RATE_LIMIT_ENABLED_FLAG = @@ -694,6 +696,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mIfaceStatsMap = mDeps.getIfaceStatsMap(); // To prevent any possible races, the flag is not allowed to change until rebooting. mSupportEventLogger = mDeps.supportEventLogger(mContext); + mStoreTransportTypes = + mDeps.isTetheringFeatureNotChickenedOut(mContext, STORE_TRANSPORT_TYPES); if (mSupportEventLogger) { mEventLogger = new NetworkStatsEventLogger(); } else { @@ -983,6 +987,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { ctx, BROADCAST_NETWORK_STATS_UPDATED_RATE_LIMIT_ENABLED_FLAG); } + /** + * @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut + */ + public boolean isTetheringFeatureNotChickenedOut(Context ctx, String feature) { + return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(ctx, feature); + } + /** * Get client side traffic stats rate-limit cache config. * @@ -1185,7 +1196,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return new NetworkStatsRecorder(new FileRotator( baseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis), mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags, - wipeOnError, useFastDataInput, baseDir); + wipeOnError, useFastDataInput, mStoreTransportTypes, baseDir); } @GuardedBy("mStatsLock") @@ -3061,6 +3072,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } pw.println(CONFIG_ENABLE_NETWORK_STATS_EVENT_LOGGER + ": " + mSupportEventLogger); + pw.println(STORE_TRANSPORT_TYPES + ": " + mStoreTransportTypes); pw.print(NETSTATS_FASTDATAINPUT_TARGET_ATTEMPTS, mDeps.getUseFastDataInputTargetAttempts()); pw.println(); @@ -3627,6 +3639,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } private final boolean mSupportEventLogger; + private final boolean mStoreTransportTypes; @GuardedBy("mStatsLock") @Nullable private final NetworkStatsEventLogger mEventLogger; diff --git a/tests/benchmark/src/android/net/netstats/benchmarktests/NetworkStatsTest.kt b/tests/benchmark/src/android/net/netstats/benchmarktests/NetworkStatsTest.kt index 57602f1017..107d80fb68 100644 --- a/tests/benchmark/src/android/net/netstats/benchmarktests/NetworkStatsTest.kt +++ b/tests/benchmark/src/android/net/netstats/benchmarktests/NetworkStatsTest.kt @@ -72,7 +72,7 @@ class NetworkStatsTest { repeat(FILE_CACHE_WARM_UP_REPEAT_COUNT) { testFilesAssets.forEach { val uidTestFiles = getSortedListForPrefix(it, "uid") - val collection = NetworkStatsCollection(UID_COLLECTION_BUCKET_DURATION_MS) + val collection = buildNetworkStatsCollection(UID_COLLECTION_BUCKET_DURATION_MS) for (file in uidTestFiles) { readFile(file, collection) } @@ -117,6 +117,13 @@ class NetworkStatsTest { BufferedInputStream(file.inputStream()).use { reader.read(it) } + + private fun buildNetworkStatsCollection(bucketDuration: Long) = + NetworkStatsCollection( + bucketDuration, + false /* useFastDataInput */, + true /* storeTransportTypes */ + ) } @Test @@ -125,7 +132,7 @@ class NetworkStatsTest { // this a number of time to have a stable number. testFilesAssets.forEach { val uidTestFiles = getSortedListForPrefix(it, "uid") - val collection = NetworkStatsCollection(UID_COLLECTION_BUCKET_DURATION_MS) + val collection = buildNetworkStatsCollection(UID_COLLECTION_BUCKET_DURATION_MS) for (file in uidTestFiles) { readFile(file, collection) } @@ -148,7 +155,10 @@ class NetworkStatsTest { testFilesAssets.forEach { val recorder = NetworkStatsRecorder( FileRotator( - it, PREFIX_UID, UID_RECORDER_ROTATE_AGE_MS, UID_RECORDER_DELETE_AGE_MS + it, + PREFIX_UID, + UID_RECORDER_ROTATE_AGE_MS, + UID_RECORDER_DELETE_AGE_MS ), mockObserver, mockDropBox, @@ -157,6 +167,7 @@ class NetworkStatsTest { false /* includeTags */, false /* wipeOnError */, useFastDataInput /* useFastDataInput */, + true /* storeTransportTypes */, it ) recorder.orLoadCompleteLocked diff --git a/tests/unit/java/android/net/NetworkIdentitySetTest.kt b/tests/unit/java/android/net/NetworkIdentitySetTest.kt index cf94e84d4c..d16a52a8ee 100644 --- a/tests/unit/java/android/net/NetworkIdentitySetTest.kt +++ b/tests/unit/java/android/net/NetworkIdentitySetTest.kt @@ -29,6 +29,7 @@ import android.net.NetworkCapabilities.TRANSPORT_ETHERNET import android.net.NetworkCapabilities.TRANSPORT_TEST import android.net.NetworkCapabilities.TRANSPORT_VPN import android.net.NetworkCapabilities.TRANSPORT_WIFI +import android.net.NetworkIdentitySet.VERSION_ADD_SUB_ID import android.net.NetworkIdentitySet.writeOptionalString import android.os.Build import android.telephony.TelephonyManager @@ -121,7 +122,7 @@ class NetworkIdentitySetTest { val baos = ByteArrayOutputStream() val outDataStream = DataOutputStream(baos) - originalSet.writeToStream(outDataStream) + originalSet.writeToStream(outDataStream, true /* storeTransportTypes */) val bais = ByteArrayInputStream(baos.toByteArray()) val inDataStream = DataInputStream(bais) @@ -151,17 +152,17 @@ class NetworkIdentitySetTest { } @Test - fun testMigrateToSupportTransportTypes() { - doTestMigrateToSupportTransportTypes(TYPE_MOBILE, TRANSPORT_CELLULAR) - doTestMigrateToSupportTransportTypes(TYPE_WIFI, TRANSPORT_WIFI) - doTestMigrateToSupportTransportTypes(TYPE_BLUETOOTH, TRANSPORT_BLUETOOTH) - doTestMigrateToSupportTransportTypes(TYPE_ETHERNET, TRANSPORT_ETHERNET) - doTestMigrateToSupportTransportTypes(TYPE_VPN, TRANSPORT_VPN) - doTestMigrateToSupportTransportTypes(TYPE_TEST, TRANSPORT_TEST) - doTestMigrateToSupportTransportTypes(TYPE_WIMAX) + fun testMigrateToStoreTransportTypes() { + doTestMigrateToStoreTransportTypes(TYPE_MOBILE, TRANSPORT_CELLULAR) + doTestMigrateToStoreTransportTypes(TYPE_WIFI, TRANSPORT_WIFI) + doTestMigrateToStoreTransportTypes(TYPE_BLUETOOTH, TRANSPORT_BLUETOOTH) + doTestMigrateToStoreTransportTypes(TYPE_ETHERNET, TRANSPORT_ETHERNET) + doTestMigrateToStoreTransportTypes(TYPE_VPN, TRANSPORT_VPN) + doTestMigrateToStoreTransportTypes(TYPE_TEST, TRANSPORT_TEST) + doTestMigrateToStoreTransportTypes(TYPE_WIMAX) } - private fun doTestMigrateToSupportTransportTypes( + private fun doTestMigrateToStoreTransportTypes( legacyNetworkType: Int, vararg expectedTransportTypes: Int ) { @@ -184,4 +185,35 @@ class NetworkIdentitySetTest { assertEquals(expectedSet, deserializedSet) } + + @Test + fun testDowngradeFromStoreTransportTypes() { + val originalSet = NetworkIdentitySet() + originalSet.add(buildNetworkIdentity(TYPE_MOBILE, TRANSPORT_CELLULAR)) + originalSet.add(buildNetworkIdentity(TYPE_WIFI, TRANSPORT_VPN, TRANSPORT_WIFI)) + + val baos = ByteArrayOutputStream() + val outDataStream = DataOutputStream(baos) + // Write to stream with storeTransportTypes disabled. + originalSet.writeToStream(outDataStream, false /* storeTransportTypes */) + + val bais = ByteArrayInputStream(baos.toByteArray()) + val inDataStream = DataInputStream(bais) + + // Verify the output is in the corresponding format. + val version = inDataStream.readInt() + val size = inDataStream.readInt() + assertEquals(VERSION_ADD_SUB_ID, version) + assertEquals(2, size) + + // Generate expected identity set with deduced transport type. + val expectedSet = NetworkIdentitySet() + expectedSet.add(buildNetworkIdentity(TYPE_MOBILE, TRANSPORT_CELLULAR)) + expectedSet.add(buildNetworkIdentity(TYPE_WIFI, TRANSPORT_WIFI)) + + // Verify the transport types are from deduced transport type. + inDataStream.reset() + val deserializedSet = NetworkIdentitySet(inDataStream) + assertEquals(expectedSet, deserializedSet) + } } diff --git a/tests/unit/java/android/net/NetworkStatsCollectionTest.java b/tests/unit/java/android/net/NetworkStatsCollectionTest.java index 5d6f980772..565211adfd 100644 --- a/tests/unit/java/android/net/NetworkStatsCollectionTest.java +++ b/tests/unit/java/android/net/NetworkStatsCollectionTest.java @@ -119,13 +119,19 @@ public class NetworkStatsCollectionTest { RecurrenceRule.sClock = Clock.fixed(instant, ZoneId.systemDefault()); } + private NetworkStatsCollection buildNetworkStatsCollection(long bucketDuration) { + return new NetworkStatsCollection(bucketDuration, false /* useFastDataInput */, + true /* storeTransportTypes */); + } + @Test public void testReadLegacyNetwork() throws Exception { final File testFile = new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); stageFile(R.raw.netstats_v1, testFile); - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); + final NetworkStatsCollection collection = + buildNetworkStatsCollection(30 * MINUTE_IN_MILLIS); collection.readLegacyNetwork(testFile); // verify that history read correctly @@ -153,7 +159,8 @@ public class NetworkStatsCollectionTest { new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); stageFile(R.raw.netstats_uid_v4, testFile); - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); + final NetworkStatsCollection collection = + buildNetworkStatsCollection(30 * MINUTE_IN_MILLIS); collection.readLegacyUid(testFile, false); // verify that history read correctly @@ -181,7 +188,8 @@ public class NetworkStatsCollectionTest { new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); stageFile(R.raw.netstats_uid_v4, testFile); - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); + final NetworkStatsCollection collection = + buildNetworkStatsCollection(30 * MINUTE_IN_MILLIS); collection.readLegacyUid(testFile, true); // verify that history read correctly @@ -208,7 +216,8 @@ public class NetworkStatsCollectionTest { new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE); stageFile(uidRes, testFile); - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); + final NetworkStatsCollection collection = + buildNetworkStatsCollection(30 * MINUTE_IN_MILLIS); collection.readLegacyUid(testFile, true); // now export into a unified format @@ -220,9 +229,11 @@ public class NetworkStatsCollectionTest { @Test public void testFastDataInputRead() throws Exception { final NetworkStatsCollection legacyCollection = - new NetworkStatsCollection(30 * MINUTE_IN_MILLIS, false /* useFastDataInput */); + new NetworkStatsCollection(30 * MINUTE_IN_MILLIS, false /* useFastDataInput */, + true /* storeTransportTypes */); final NetworkStatsCollection fastReadCollection = - new NetworkStatsCollection(30 * MINUTE_IN_MILLIS, true /* useFastDataInput */); + new NetworkStatsCollection(30 * MINUTE_IN_MILLIS, true /* useFastDataInput */, + true /* storeTransportTypes */); final InputStream bis = getUidInputStreamFromRes(R.raw.netstats_uid_v4); legacyCollection.read(bis); bis.reset(); @@ -232,7 +243,7 @@ public class NetworkStatsCollectionTest { @Test public void testStartEndAtomicBuckets() throws Exception { - final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS); + final NetworkStatsCollection collection = buildNetworkStatsCollection(HOUR_IN_MILLIS); // record empty data straddling between buckets final NetworkStats.Entry entry = new NetworkStats.Entry(); @@ -247,7 +258,7 @@ public class NetworkStatsCollectionTest { @Test public void testAccessLevels() throws Exception { - final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS); + final NetworkStatsCollection collection = buildNetworkStatsCollection(HOUR_IN_MILLIS); final NetworkStats.Entry entry = new NetworkStats.Entry(); final NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, @@ -314,8 +325,9 @@ public class NetworkStatsCollectionTest { stageFile(R.raw.netstats_v1, testFile); final NetworkStatsCollection emptyCollection = - new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); - final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS); + buildNetworkStatsCollection(30 * MINUTE_IN_MILLIS); + final NetworkStatsCollection collection = + buildNetworkStatsCollection(30 * MINUTE_IN_MILLIS); collection.readLegacyNetwork(testFile); // We're in the future, but not that far off @@ -511,7 +523,7 @@ public class NetworkStatsCollectionTest { setClock(Instant.parse("2012-06-01T00:00:00.00Z")); // Create a simple history with a ton of measured usage - final NetworkStatsCollection large = new NetworkStatsCollection(HOUR_IN_MILLIS); + final NetworkStatsCollection large = buildNetworkStatsCollection(HOUR_IN_MILLIS); final NetworkIdentitySet ident = new NetworkIdentitySet(); ident.add(new NetworkIdentity(ConnectivityManager.TYPE_MOBILE, -1, TEST_IMSI, null, false, true, true, OEM_NONE, TEST_SUBID, @@ -532,7 +544,7 @@ public class NetworkStatsCollectionTest { @Test public void testRounding() throws Exception { - final NetworkStatsCollection coll = new NetworkStatsCollection(HOUR_IN_MILLIS); + final NetworkStatsCollection coll = buildNetworkStatsCollection(HOUR_IN_MILLIS); // Special values should remain unchanged for (long time : new long[] { diff --git a/tests/unit/java/android/net/NetworkStatsRecorderTest.java b/tests/unit/java/android/net/NetworkStatsRecorderTest.java index a0b36bb0e9..a6655373bc 100644 --- a/tests/unit/java/android/net/NetworkStatsRecorderTest.java +++ b/tests/unit/java/android/net/NetworkStatsRecorderTest.java @@ -83,10 +83,16 @@ public final class NetworkStatsRecorderTest { MockitoAnnotations.initMocks(this); } + private NetworkStatsCollection buildNetworkStatsCollection(long bucketDuration) { + return new NetworkStatsCollection(bucketDuration, false /* useFastDataInput */, + true /* storeTransportTypes */); + } + private NetworkStatsRecorder buildRecorder(FileRotator rotator, boolean wipeOnError) { return new NetworkStatsRecorder(rotator, mObserver, mDropBox, TEST_PREFIX, HOUR_IN_MILLIS, false /* includeTags */, wipeOnError, - false /* useFastDataInput */, null /* baseDir */); + false /* useFastDataInput */, true /* storeTransportType */, + null /* baseDir */); } @Test @@ -110,7 +116,7 @@ public final class NetworkStatsRecorderTest { @Test public void testFileReadingMetrics_empty() { - final NetworkStatsCollection collection = new NetworkStatsCollection(30); + final NetworkStatsCollection collection = buildNetworkStatsCollection(30); final NetworkStatsMetricsLogger.Dependencies deps = mock(NetworkStatsMetricsLogger.Dependencies.class); final NetworkStatsMetricsLogger logger = new NetworkStatsMetricsLogger(deps); @@ -146,7 +152,7 @@ public final class NetworkStatsRecorderTest { @Test public void testFileReadingMetrics() { - final NetworkStatsCollection collection = new NetworkStatsCollection(30); + final NetworkStatsCollection collection = buildNetworkStatsCollection(30); final NetworkStats.Entry entry = new NetworkStats.Entry(); final NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity.Builder().build()); @@ -177,7 +183,7 @@ public final class NetworkStatsRecorderTest { @Test public void testFileReadingMetrics_fileAttributes() throws IOException { - final NetworkStatsCollection collection = new NetworkStatsCollection(30); + final NetworkStatsCollection collection = buildNetworkStatsCollection(30); // Create files for testing. Only the first and the third files should be counted, // with total 26 (each char takes 2 bytes) bytes in the content. diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java index 955701e8ec..7694e46ff9 100644 --- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java @@ -619,6 +619,12 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { return true; } + @Override + public boolean isTetheringFeatureNotChickenedOut(@NonNull Context cts, + @NonNull String feature) { + return mFeatureFlags.getOrDefault(feature, true); + } + @Override public boolean isTrafficStatsServiceRateLimitCacheEnabled(Context ctx, boolean isClientCacheEnabled) { @@ -2676,7 +2682,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { return new NetworkStatsRecorder(new FileRotator( directory, prefix, config.rotateAgeMillis, config.deleteAgeMillis), observer, dropBox, prefix, config.bucketDuration, includeTags, wipeOnError, - false /* useFastDataInput */, directory); + false /* useFastDataInput */, true /* storeTransportTypes */, directory); } private NetworkStatsCollection getLegacyCollection(String prefix, boolean includeTags) {