From ee3ea79c3811a6d8d801b24b769f4fef9dacddf6 Mon Sep 17 00:00:00 2001 From: junyulai Date: Fri, 15 May 2020 18:26:25 +0800 Subject: [PATCH] [SM14] Create new puller for reporting data usage per rat Test: adb shell cmd stats pull-source 10082, 10000~10003 Test: atest UidAtomTests#testMobileBytesTransfer \ UidAtomTests#testMobileBytesTransferByFgBg \ UidAtomTests#testDataUsageBytesTransfer Bug: 129082217 Change-Id: If9948e37980e9de342f84e5fde3088fac7f36a15 Change-Id: I7d3931c3b10e377abdf1ab6fcb67100dcdf1f96d --- .../stats/pull/StatsPullAtomService.java | 131 ++++++++++++++---- 1 file changed, 104 insertions(+), 27 deletions(-) diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 0b3254f53324c..643bf44acd59b 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -24,6 +24,10 @@ import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; +import static android.net.NetworkTemplate.buildTemplateMobileWildcard; +import static android.net.NetworkTemplate.buildTemplateMobileWithRatType; +import static android.net.NetworkTemplate.buildTemplateWifiWildcard; +import static android.net.NetworkTemplate.getAllCollapsedRatTypes; import static android.os.Debug.getIonHeapsSizeKb; import static android.os.Process.getUidForPid; import static android.os.storage.VolumeInfo.TYPE_PRIVATE; @@ -327,6 +331,7 @@ public class StatsPullAtomService extends SystemService { case FrameworkStatsLog.MOBILE_BYTES_TRANSFER: case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: + case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: return pullDataBytesTransfer(atomTag, data); case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER: return pullBluetoothBytesTransfer(atomTag, data); @@ -645,12 +650,15 @@ public class StatsPullAtomService extends SystemService { FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG)); mNetworkStatsBaselines.addAll(collectNetworkStatsSnapshotForAtom( FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED)); + mNetworkStatsBaselines.addAll( + collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER)); registerWifiBytesTransfer(); registerWifiBytesTransferBackground(); registerMobileBytesTransfer(); registerMobileBytesTransferBackground(); registerBytesTransferByTagAndMetered(); + registerDataUsageBytesTransfer(); } /** @@ -796,13 +804,15 @@ public class StatsPullAtomService extends SystemService { public final boolean slicedByFgbg; public final boolean slicedByTag; public final boolean slicedByMetered; + public final int ratType; NetworkStatsExt(@NonNull NetworkStats stats, int[] transports, boolean slicedByFgbg) { - this(stats, transports, slicedByFgbg, /*slicedByTag=*/false, /*slicedByMetered=*/false); + this(stats, transports, slicedByFgbg, /*slicedByTag=*/false, /*slicedByMetered=*/false, + TelephonyManager.NETWORK_TYPE_UNKNOWN); } NetworkStatsExt(@NonNull NetworkStats stats, int[] transports, boolean slicedByFgbg, - boolean slicedByTag, boolean slicedByMetered) { + boolean slicedByTag, boolean slicedByMetered, int ratType) { this.stats = stats; // Sort transports array so that we can test for equality without considering order. @@ -812,11 +822,13 @@ public class StatsPullAtomService extends SystemService { this.slicedByFgbg = slicedByFgbg; this.slicedByTag = slicedByTag; this.slicedByMetered = slicedByMetered; + this.ratType = ratType; } public boolean hasSameSlicing(@NonNull NetworkStatsExt other) { return Arrays.equals(transports, other.transports) && slicedByFgbg == other.slicedByFgbg - && slicedByTag == other.slicedByTag && slicedByMetered == other.slicedByMetered; + && slicedByTag == other.slicedByTag && slicedByMetered == other.slicedByMetered + && ratType == other.ratType; } } @@ -825,8 +837,7 @@ public class StatsPullAtomService extends SystemService { List ret = new ArrayList<>(); switch(atomTag) { case FrameworkStatsLog.WIFI_BYTES_TRANSFER: { - final NetworkStats stats = getUidNetworkStatsSnapshot(TRANSPORT_WIFI, - /*includeTags=*/false); + final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI); if (stats != null) { ret.add(new NetworkStatsExt(stats.groupedByUid(), new int[] {TRANSPORT_WIFI}, /*slicedByFgbg=*/false)); @@ -834,8 +845,7 @@ public class StatsPullAtomService extends SystemService { break; } case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: { - final NetworkStats stats = getUidNetworkStatsSnapshot(TRANSPORT_WIFI, - /*includeTags=*/false); + final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI); if (stats != null) { ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats), new int[] {TRANSPORT_WIFI}, /*slicedByFgbg=*/true)); @@ -843,8 +853,8 @@ public class StatsPullAtomService extends SystemService { break; } case FrameworkStatsLog.MOBILE_BYTES_TRANSFER: { - final NetworkStats stats = getUidNetworkStatsSnapshot(TRANSPORT_CELLULAR, - /*includeTags=*/false); + final NetworkStats stats = + getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR); if (stats != null) { ret.add(new NetworkStatsExt(stats.groupedByUid(), new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/false)); @@ -852,8 +862,8 @@ public class StatsPullAtomService extends SystemService { break; } case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: { - final NetworkStats stats = getUidNetworkStatsSnapshot(TRANSPORT_CELLULAR, - /*includeTags=*/false); + final NetworkStats stats = + getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR); if (stats != null) { ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats), new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true)); @@ -861,16 +871,29 @@ public class StatsPullAtomService extends SystemService { break; } case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: { - final NetworkStats wifiStats = getUidNetworkStatsSnapshot(TRANSPORT_WIFI, - /*includeTags=*/true); - final NetworkStats cellularStats = getUidNetworkStatsSnapshot(TRANSPORT_CELLULAR, - /*includeTags=*/true); + final NetworkStats wifiStats = getUidNetworkStatsSnapshotForTemplate( + buildTemplateWifiWildcard(), /*includeTags=*/true); + final NetworkStats cellularStats = getUidNetworkStatsSnapshotForTemplate( + buildTemplateMobileWildcard(), /*includeTags=*/true); if (wifiStats != null && cellularStats != null) { final NetworkStats stats = wifiStats.add(cellularStats); ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats), - new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR}, - /*slicedByFgbg=*/false, /*slicedByTag=*/true, - /*slicedByMetered=*/true)); + new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR}, + /*slicedByFgbg=*/false, /*slicedByTag=*/true, + /*slicedByMetered=*/true, TelephonyManager.NETWORK_TYPE_UNKNOWN)); + } + break; + } + case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: { + for (final int ratType : getAllCollapsedRatTypes()) { + final NetworkTemplate template = buildTemplateMobileWithRatType(null, ratType); + final NetworkStats stats = + getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false); + if (stats != null) { + ret.add(new NetworkStatsExt(sliceNetworkStatsByFgbg(stats), + new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true, + /*slicedByTag=*/false, /*slicedByMetered=*/false, ratType)); + } } break; } @@ -901,7 +924,7 @@ public class StatsPullAtomService extends SystemService { } final NetworkStatsExt diff = new NetworkStatsExt( item.stats.subtract(baseline.stats).removeEmptyEntries(), item.transports, - item.slicedByFgbg, item.slicedByTag, item.slicedByMetered); + item.slicedByFgbg, item.slicedByTag, item.slicedByMetered, item.ratType); // If no diff, skip. if (diff.stats.size() == 0) continue; @@ -910,6 +933,9 @@ public class StatsPullAtomService extends SystemService { case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: addBytesTransferByTagAndMeteredAtoms(diff, pulledData); break; + case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: + addDataUsageBytesTransferAtoms(diff, pulledData); + break; default: addNetworkStats(atomTag, pulledData, diff); } @@ -966,18 +992,49 @@ public class StatsPullAtomService extends SystemService { } } + private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt, + @NonNull List pulledData) { + final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling + for (int i = 0; i < statsExt.stats.size(); i++) { + statsExt.stats.getValues(i, entry); + StatsEvent e = StatsEvent.newBuilder() + .setAtomId(FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER) + .addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true) + .writeInt(entry.set) + .writeLong(entry.rxBytes) + .writeLong(entry.rxPackets) + .writeLong(entry.txBytes) + .writeLong(entry.txPackets) + .writeInt(statsExt.ratType) + // TODO: Fill information about subscription. + .writeString(/*sim_mcc=*/null) + .writeString(/*sim_mnc=*/null) + .writeInt(/*carrier_id=*/0) + .writeInt(/*opportunistic_data_sub=*/0) + .build(); + pulledData.add(e); + } + } + /** - * Create a snapshot of NetworkStats since boot, but add 1 bucket duration before boot as a - * buffer to ensure at least one full bucket will be included. + * Create a snapshot of NetworkStats for a given transport. + */ + @Nullable private NetworkStats getUidNetworkStatsSnapshotForTransport(int transport) { + final NetworkTemplate template = (transport == TRANSPORT_CELLULAR) + ? NetworkTemplate.buildTemplateMobileWithRatType( + /*subscriptionId=*/null, NETWORK_TYPE_ALL) + : NetworkTemplate.buildTemplateWifiWildcard(); + return getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false); + } + + /** + * Create a snapshot of NetworkStats since boot for the given template, but add 1 bucket + * duration before boot as a buffer to ensure at least one full bucket will be included. * Note that this should be only used to calculate diff since the snapshot might contains * some traffic before boot. */ - @Nullable private NetworkStats getUidNetworkStatsSnapshot(int transport, boolean includeTags) { - final NetworkTemplate template = (transport == TRANSPORT_CELLULAR) - ? NetworkTemplate.buildTemplateMobileWithRatType( - /*subscriptionId=*/null, NETWORK_TYPE_ALL) - : NetworkTemplate.buildTemplateWifiWildcard(); - + @Nullable private NetworkStats getUidNetworkStatsSnapshotForTemplate( + @NonNull NetworkTemplate template, boolean includeTags) { final long elapsedMillisSinceBoot = SystemClock.elapsedRealtime(); final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro()); final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(), @@ -994,6 +1051,13 @@ public class StatsPullAtomService extends SystemService { return null; } + @NonNull private NetworkStats sliceNetworkStatsByFgbg(@NonNull NetworkStats stats) { + return sliceNetworkStats(stats, + (newEntry, oldEntry) -> { + newEntry.set = oldEntry.set; + }); + } + @NonNull private NetworkStats sliceNetworkStatsByUidAndFgbg(@NonNull NetworkStats stats) { return sliceNetworkStats(stats, (newEntry, oldEntry) -> { @@ -1113,6 +1177,19 @@ public class StatsPullAtomService extends SystemService { ); } + private void registerDataUsageBytesTransfer() { + int tagId = FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER; + PullAtomMetadata metadata = new PullAtomMetadata.Builder() + .setAdditiveFields(new int[] {2, 3, 4, 5}) + .build(); + mStatsManager.setPullAtomCallback( + tagId, + metadata, + BackgroundThread.getExecutor(), + mStatsCallbackImpl + ); + } + private void registerBluetoothBytesTransfer() { int tagId = FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER; PullAtomMetadata metadata = new PullAtomMetadata.Builder()