Merge "[AF02.1] Support read by FastDataInput in the NetworkStatsRecorder" into main
This commit is contained in:
commit
962515a8a8
8 changed files with 81 additions and 11 deletions
|
|
@ -57,6 +57,10 @@ java_defaults {
|
|||
"app-compat-annotations",
|
||||
"androidx.annotation_annotation",
|
||||
],
|
||||
static_libs: [
|
||||
// Cannot go to framework-connectivity because mid_sdk checks require 31.
|
||||
"modules-utils-binary-xml",
|
||||
],
|
||||
impl_only_libs: [
|
||||
// The build system will use framework-bluetooth module_current stubs, because
|
||||
// of sdk_version: "module_current" above.
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ import android.util.proto.ProtoOutputStream;
|
|||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.FileRotator;
|
||||
import com.android.modules.utils.FastDataInput;
|
||||
import com.android.net.module.util.CollectionUtils;
|
||||
import com.android.net.module.util.NetworkStatsUtils;
|
||||
|
||||
|
|
@ -116,15 +117,28 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W
|
|||
private long mEndMillis;
|
||||
private long mTotalBytes;
|
||||
private boolean mDirty;
|
||||
private final boolean mUseFastDataInput;
|
||||
|
||||
/**
|
||||
* Construct a {@link NetworkStatsCollection} object.
|
||||
*
|
||||
* @param bucketDuration duration of the buckets in this object, in milliseconds.
|
||||
* @param bucketDurationMillis duration of the buckets in this object, in milliseconds.
|
||||
* @hide
|
||||
*/
|
||||
public NetworkStatsCollection(long bucketDurationMillis) {
|
||||
this(bucketDurationMillis, false /* useFastDataInput */);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @hide
|
||||
*/
|
||||
public NetworkStatsCollection(long bucketDurationMillis, boolean useFastDataInput) {
|
||||
mBucketDurationMillis = bucketDurationMillis;
|
||||
mUseFastDataInput = useFastDataInput;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +497,11 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W
|
|||
/** @hide */
|
||||
@Override
|
||||
public void read(InputStream in) throws IOException {
|
||||
read((DataInput) new DataInputStream(in));
|
||||
if (mUseFastDataInput) {
|
||||
read(FastDataInput.obtain(in));
|
||||
} else {
|
||||
read((DataInput) new DataInputStream(in));
|
||||
}
|
||||
}
|
||||
|
||||
private void read(DataInput in) throws IOException {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ public class NetworkStatsRecorder {
|
|||
private final long mBucketDuration;
|
||||
private final boolean mOnlyTags;
|
||||
private final boolean mWipeOnError;
|
||||
private final boolean mUseFastDataInput;
|
||||
|
||||
private long mPersistThresholdBytes = 2 * MB_IN_BYTES;
|
||||
private NetworkStats mLastSnapshot;
|
||||
|
|
@ -104,6 +105,7 @@ public class NetworkStatsRecorder {
|
|||
mBucketDuration = YEAR_IN_MILLIS;
|
||||
mOnlyTags = false;
|
||||
mWipeOnError = true;
|
||||
mUseFastDataInput = false;
|
||||
|
||||
mPending = null;
|
||||
mSinceBoot = new NetworkStatsCollection(mBucketDuration);
|
||||
|
|
@ -116,7 +118,7 @@ public class NetworkStatsRecorder {
|
|||
*/
|
||||
public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
|
||||
DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags,
|
||||
boolean wipeOnError) {
|
||||
boolean wipeOnError, boolean useFastDataInput) {
|
||||
mRotator = Objects.requireNonNull(rotator, "missing FileRotator");
|
||||
mObserver = Objects.requireNonNull(observer, "missing NonMonotonicObserver");
|
||||
mDropBox = Objects.requireNonNull(dropBox, "missing DropBoxManager");
|
||||
|
|
@ -125,6 +127,7 @@ public class NetworkStatsRecorder {
|
|||
mBucketDuration = bucketDuration;
|
||||
mOnlyTags = onlyTags;
|
||||
mWipeOnError = wipeOnError;
|
||||
mUseFastDataInput = useFastDataInput;
|
||||
|
||||
mPending = new NetworkStatsCollection(bucketDuration);
|
||||
mSinceBoot = new NetworkStatsCollection(bucketDuration);
|
||||
|
|
@ -195,8 +198,12 @@ public class NetworkStatsRecorder {
|
|||
}
|
||||
|
||||
private NetworkStatsCollection loadLocked(long start, long end) {
|
||||
if (LOGD) Log.d(TAG, "loadLocked() reading from disk for " + mCookie);
|
||||
final NetworkStatsCollection res = new NetworkStatsCollection(mBucketDuration);
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "loadLocked() reading from disk for " + mCookie
|
||||
+ " useFastDataInput: " + mUseFastDataInput);
|
||||
}
|
||||
final NetworkStatsCollection res =
|
||||
new NetworkStatsCollection(mBucketDuration, mUseFastDataInput);
|
||||
try {
|
||||
mRotator.readMatching(res, start, end);
|
||||
res.recordCollection(mPending);
|
||||
|
|
|
|||
|
|
@ -969,7 +969,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);
|
||||
wipeOnError, false /* useFastDataInput */);
|
||||
}
|
||||
|
||||
@GuardedBy("mStatsLock")
|
||||
|
|
|
|||
|
|
@ -133,7 +133,16 @@ class NetworkStatsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun testReadFromRecorder_manyUids() {
|
||||
fun testReadFromRecorder_manyUids_useDataInput() {
|
||||
doTestReadFromRecorder_manyUids(useFastDataInput = false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReadFromRecorder_manyUids_useFastDataInput() {
|
||||
doTestReadFromRecorder_manyUids(useFastDataInput = true)
|
||||
}
|
||||
|
||||
fun doTestReadFromRecorder_manyUids(useFastDataInput: Boolean) {
|
||||
val mockObserver = mock<NonMonotonicObserver<String>>()
|
||||
val mockDropBox = mock<DropBoxManager>()
|
||||
testFilesAssets.forEach {
|
||||
|
|
@ -146,7 +155,8 @@ class NetworkStatsTest {
|
|||
PREFIX_UID,
|
||||
UID_COLLECTION_BUCKET_DURATION_MS,
|
||||
false /* includeTags */,
|
||||
false /* wipeOnError */
|
||||
false /* wipeOnError */,
|
||||
useFastDataInput /* useFastDataInput */
|
||||
)
|
||||
recorder.orLoadCompleteLocked
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import libcore.io.Streams;
|
|||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
|
|
@ -90,7 +91,8 @@ import java.util.Set;
|
|||
@SmallTest
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(SC_V2) // TODO: Use to Build.VERSION_CODES.SC_V2 when available
|
||||
public class NetworkStatsCollectionTest {
|
||||
|
||||
@Rule
|
||||
public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
|
||||
private static final String TEST_FILE = "test.bin";
|
||||
private static final String TEST_IMSI = "310260000000000";
|
||||
private static final int TEST_SUBID = 1;
|
||||
|
|
@ -199,6 +201,33 @@ public class NetworkStatsCollectionTest {
|
|||
77017831L, 100995L, 35436758L, 92344L);
|
||||
}
|
||||
|
||||
private InputStream getUidInputStreamFromRes(int uidRes) throws Exception {
|
||||
final File testFile =
|
||||
new File(InstrumentationRegistry.getContext().getFilesDir(), TEST_FILE);
|
||||
stageFile(uidRes, testFile);
|
||||
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
|
||||
collection.readLegacyUid(testFile, true);
|
||||
|
||||
// now export into a unified format
|
||||
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
collection.write(bos);
|
||||
return new ByteArrayInputStream(bos.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFastDataInputRead() throws Exception {
|
||||
final NetworkStatsCollection legacyCollection =
|
||||
new NetworkStatsCollection(30 * MINUTE_IN_MILLIS, false /* useFastDataInput */);
|
||||
final NetworkStatsCollection fastReadCollection =
|
||||
new NetworkStatsCollection(30 * MINUTE_IN_MILLIS, true /* useFastDataInput */);
|
||||
final InputStream bis = getUidInputStreamFromRes(R.raw.netstats_uid_v4);
|
||||
legacyCollection.read(bis);
|
||||
bis.reset();
|
||||
fastReadCollection.read(bis);
|
||||
assertCollectionEntries(legacyCollection.getEntries(), fastReadCollection);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartEndAtomicBuckets() throws Exception {
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(HOUR_IN_MILLIS);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ public final class NetworkStatsRecorderTest {
|
|||
|
||||
private NetworkStatsRecorder buildRecorder(FileRotator rotator, boolean wipeOnError) {
|
||||
return new NetworkStatsRecorder(rotator, mObserver, mDropBox, TEST_PREFIX,
|
||||
HOUR_IN_MILLIS, false /* includeTags */, wipeOnError);
|
||||
HOUR_IN_MILLIS, false /* includeTags */, wipeOnError,
|
||||
false /* useFastDataInput */);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -2230,7 +2230,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||
final DropBoxManager dropBox = mock(DropBoxManager.class);
|
||||
return new NetworkStatsRecorder(new FileRotator(
|
||||
directory, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
|
||||
observer, dropBox, prefix, config.bucketDuration, includeTags, wipeOnError);
|
||||
observer, dropBox, prefix, config.bucketDuration, includeTags, wipeOnError,
|
||||
false /* useFastDataInput */);
|
||||
}
|
||||
|
||||
private NetworkStatsCollection getLegacyCollection(String prefix, boolean includeTags) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue