Loading services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +102 −25 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); } /** Loading Loading @@ -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. Loading @@ -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; } } Loading @@ -825,8 +837,7 @@ public class StatsPullAtomService extends SystemService { List<NetworkStatsExt> 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)); Loading @@ -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)); Loading @@ -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)); Loading @@ -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)); Loading @@ -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)); /*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; } Loading Loading @@ -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; Loading @@ -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); } Loading Loading @@ -966,18 +992,49 @@ public class StatsPullAtomService extends SystemService { } } private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> 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. * Note that this should be only used to calculate diff since the snapshot might contains * some traffic before boot. * Create a snapshot of NetworkStats for a given transport. */ @Nullable private NetworkStats getUidNetworkStatsSnapshot(int transport, boolean includeTags) { @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 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(), Loading @@ -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) -> { Loading Loading @@ -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() Loading Loading
services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +102 −25 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); } /** Loading Loading @@ -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. Loading @@ -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; } } Loading @@ -825,8 +837,7 @@ public class StatsPullAtomService extends SystemService { List<NetworkStatsExt> 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)); Loading @@ -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)); Loading @@ -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)); Loading @@ -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)); Loading @@ -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)); /*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; } Loading Loading @@ -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; Loading @@ -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); } Loading Loading @@ -966,18 +992,49 @@ public class StatsPullAtomService extends SystemService { } } private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> 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. * Note that this should be only used to calculate diff since the snapshot might contains * some traffic before boot. * Create a snapshot of NetworkStats for a given transport. */ @Nullable private NetworkStats getUidNetworkStatsSnapshot(int transport, boolean includeTags) { @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 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(), Loading @@ -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) -> { Loading Loading @@ -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() Loading