Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb8aa00a authored by junyulai's avatar junyulai Committed by Automerger Merge Worker
Browse files

[SM14] Create new puller for reporting data usage per rat am: ee3ea79c am: 43fb9836

Change-Id: I54fab2631d11b8e5f9f88192333308928f126b8b
parents c470310f 43fb9836
Loading
Loading
Loading
Loading
+102 −25
Original line number Diff line number Diff line
@@ -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<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));
@@ -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));
                            /*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<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(),
@@ -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()