private void dumpProtoAppsLocked()

in android/os/BatteryStats.java [7110:7564]


    private void dumpProtoAppsLocked(ProtoOutputStream proto, BatteryStatsHelper helper,
            List<ApplicationInfo> apps) {
        final int which = STATS_SINCE_CHARGED;
        final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
        final long rawRealtimeMs = SystemClock.elapsedRealtime();
        final long rawRealtimeUs = rawRealtimeMs * 1000;
        final long batteryUptimeUs = getBatteryUptime(rawUptimeUs);

        SparseArray<ArrayList<String>> aidToPackages = new SparseArray<>();
        if (apps != null) {
            for (int i = 0; i < apps.size(); ++i) {
                ApplicationInfo ai = apps.get(i);
                int aid = UserHandle.getAppId(ai.uid);
                ArrayList<String> pkgs = aidToPackages.get(aid);
                if (pkgs == null) {
                    pkgs = new ArrayList<String>();
                    aidToPackages.put(aid, pkgs);
                }
                pkgs.add(ai.packageName);
            }
        }

        SparseArray<BatterySipper> uidToSipper = new SparseArray<>();
        final List<BatterySipper> sippers = helper.getUsageList();
        if (sippers != null) {
            for (int i = 0; i < sippers.size(); ++i) {
                final BatterySipper bs = sippers.get(i);
                if (bs.drainType != BatterySipper.DrainType.APP) {
                    // Others are handled by dumpProtoSystemLocked()
                    continue;
                }
                uidToSipper.put(bs.uidObj.getUid(), bs);
            }
        }

        SparseArray<? extends Uid> uidStats = getUidStats();
        final int n = uidStats.size();
        for (int iu = 0; iu < n; ++iu) {
            final long uTkn = proto.start(BatteryStatsProto.UIDS);
            final Uid u = uidStats.valueAt(iu);

            final int uid = uidStats.keyAt(iu);
            proto.write(UidProto.UID, uid);

            // Print packages and apk stats (UID_DATA & APK_DATA)
            ArrayList<String> pkgs = aidToPackages.get(UserHandle.getAppId(uid));
            if (pkgs == null) {
                pkgs = new ArrayList<String>();
            }
            final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats =
                    u.getPackageStats();
            for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
                String pkg = packageStats.keyAt(ipkg);
                final ArrayMap<String, ? extends  Uid.Pkg.Serv> serviceStats =
                        packageStats.valueAt(ipkg).getServiceStats();
                if (serviceStats.size() == 0) {
                    // Due to the way ActivityManagerService logs wakeup alarms, some packages (for
                    // example, "android") may be included in the packageStats that aren't part of
                    // the UID. If they don't have any services, then they shouldn't be listed here.
                    // These packages won't be a part in the pkgs List.
                    continue;
                }

                final long pToken = proto.start(UidProto.PACKAGES);
                proto.write(UidProto.Package.NAME, pkg);
                // Remove from the packages list since we're logging it here.
                pkgs.remove(pkg);

                for (int isvc = serviceStats.size() - 1; isvc >= 0; --isvc) {
                    final BatteryStats.Uid.Pkg.Serv ss = serviceStats.valueAt(isvc);

                    final long startTimeMs = roundUsToMs(ss.getStartTime(batteryUptimeUs, which));
                    final int starts = ss.getStarts(which);
                    final int launches = ss.getLaunches(which);
                    if (startTimeMs == 0 && starts == 0 && launches == 0) {
                        continue;
                    }

                    long sToken = proto.start(UidProto.Package.SERVICES);

                    proto.write(UidProto.Package.Service.NAME, serviceStats.keyAt(isvc));
                    proto.write(UidProto.Package.Service.START_DURATION_MS, startTimeMs);
                    proto.write(UidProto.Package.Service.START_COUNT, starts);
                    proto.write(UidProto.Package.Service.LAUNCH_COUNT, launches);

                    proto.end(sToken);
                }
                proto.end(pToken);
            }
            // Print any remaining packages that weren't in the packageStats map. pkgs is pulled
            // from PackageManager data. Packages are only included in packageStats if there was
            // specific data tracked for them (services and wakeup alarms, etc.).
            for (String p : pkgs) {
                final long pToken = proto.start(UidProto.PACKAGES);
                proto.write(UidProto.Package.NAME, p);
                proto.end(pToken);
            }

            // Total wakelock data (AGGREGATED_WAKELOCK_DATA)
            if (u.getAggregatedPartialWakelockTimer() != null) {
                final Timer timer = u.getAggregatedPartialWakelockTimer();
                // Times are since reset (regardless of 'which')
                final long totTimeMs = timer.getTotalDurationMsLocked(rawRealtimeMs);
                final Timer bgTimer = timer.getSubTimer();
                final long bgTimeMs = bgTimer != null
                        ? bgTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                final long awToken = proto.start(UidProto.AGGREGATED_WAKELOCK);
                proto.write(UidProto.AggregatedWakelock.PARTIAL_DURATION_MS, totTimeMs);
                proto.write(UidProto.AggregatedWakelock.BACKGROUND_PARTIAL_DURATION_MS, bgTimeMs);
                proto.end(awToken);
            }

            // Audio (AUDIO_DATA)
            dumpTimer(proto, UidProto.AUDIO, u.getAudioTurnedOnTimer(), rawRealtimeUs, which);

            // Bluetooth Controller (BLUETOOTH_CONTROLLER_DATA)
            dumpControllerActivityProto(proto, UidProto.BLUETOOTH_CONTROLLER,
                    u.getBluetoothControllerActivity(), which);

            // BLE scans (BLUETOOTH_MISC_DATA) (uses totalDurationMsLocked and MaxDurationMsLocked)
            final Timer bleTimer = u.getBluetoothScanTimer();
            if (bleTimer != null) {
                final long bmToken = proto.start(UidProto.BLUETOOTH_MISC);

                dumpTimer(proto, UidProto.BluetoothMisc.APPORTIONED_BLE_SCAN, bleTimer,
                        rawRealtimeUs, which);
                dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN,
                        u.getBluetoothScanBackgroundTimer(), rawRealtimeUs, which);
                // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
                dumpTimer(proto, UidProto.BluetoothMisc.UNOPTIMIZED_BLE_SCAN,
                        u.getBluetoothUnoptimizedScanTimer(), rawRealtimeUs, which);
                // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
                dumpTimer(proto, UidProto.BluetoothMisc.BACKGROUND_UNOPTIMIZED_BLE_SCAN,
                        u.getBluetoothUnoptimizedScanBackgroundTimer(), rawRealtimeUs, which);
                // Result counters
                proto.write(UidProto.BluetoothMisc.BLE_SCAN_RESULT_COUNT,
                        u.getBluetoothScanResultCounter() != null
                            ? u.getBluetoothScanResultCounter().getCountLocked(which) : 0);
                proto.write(UidProto.BluetoothMisc.BACKGROUND_BLE_SCAN_RESULT_COUNT,
                        u.getBluetoothScanResultBgCounter() != null
                            ? u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0);

                proto.end(bmToken);
            }

            // Camera (CAMERA_DATA)
            dumpTimer(proto, UidProto.CAMERA, u.getCameraTurnedOnTimer(), rawRealtimeUs, which);

            // CPU stats (CPU_DATA & CPU_TIMES_AT_FREQ_DATA)
            final long cpuToken = proto.start(UidProto.CPU);
            proto.write(UidProto.Cpu.USER_DURATION_MS, roundUsToMs(u.getUserCpuTimeUs(which)));
            proto.write(UidProto.Cpu.SYSTEM_DURATION_MS, roundUsToMs(u.getSystemCpuTimeUs(which)));

            final long[] cpuFreqs = getCpuFreqs();
            if (cpuFreqs != null) {
                final long[] cpuFreqTimeMs = u.getCpuFreqTimes(which);
                // If total cpuFreqTimes is null, then we don't need to check for
                // screenOffCpuFreqTimes.
                if (cpuFreqTimeMs != null && cpuFreqTimeMs.length == cpuFreqs.length) {
                    long[] screenOffCpuFreqTimeMs = u.getScreenOffCpuFreqTimes(which);
                    if (screenOffCpuFreqTimeMs == null) {
                        screenOffCpuFreqTimeMs = new long[cpuFreqTimeMs.length];
                    }
                    for (int ic = 0; ic < cpuFreqTimeMs.length; ++ic) {
                        long cToken = proto.start(UidProto.Cpu.BY_FREQUENCY);
                        proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
                        proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
                                cpuFreqTimeMs[ic]);
                        proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
                                screenOffCpuFreqTimeMs[ic]);
                        proto.end(cToken);
                    }
                }
            }

            for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
                final long[] timesMs = u.getCpuFreqTimes(which, procState);
                if (timesMs != null && timesMs.length == cpuFreqs.length) {
                    long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(which, procState);
                    if (screenOffTimesMs == null) {
                        screenOffTimesMs = new long[timesMs.length];
                    }
                    final long procToken = proto.start(UidProto.Cpu.BY_PROCESS_STATE);
                    proto.write(UidProto.Cpu.ByProcessState.PROCESS_STATE, procState);
                    for (int ic = 0; ic < timesMs.length; ++ic) {
                        long cToken = proto.start(UidProto.Cpu.ByProcessState.BY_FREQUENCY);
                        proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
                        proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
                                timesMs[ic]);
                        proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
                                screenOffTimesMs[ic]);
                        proto.end(cToken);
                    }
                    proto.end(procToken);
                }
            }
            proto.end(cpuToken);

            // Flashlight (FLASHLIGHT_DATA)
            dumpTimer(proto, UidProto.FLASHLIGHT, u.getFlashlightTurnedOnTimer(),
                    rawRealtimeUs, which);

            // Foreground activity (FOREGROUND_ACTIVITY_DATA)
            dumpTimer(proto, UidProto.FOREGROUND_ACTIVITY, u.getForegroundActivityTimer(),
                    rawRealtimeUs, which);

            // Foreground service (FOREGROUND_SERVICE_DATA)
            dumpTimer(proto, UidProto.FOREGROUND_SERVICE, u.getForegroundServiceTimer(),
                    rawRealtimeUs, which);

            // Job completion (JOB_COMPLETION_DATA)
            final ArrayMap<String, SparseIntArray> completions = u.getJobCompletionStats();
            final int[] reasons = new int[]{
                JobParameters.REASON_CANCELED,
                JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED,
                JobParameters.REASON_PREEMPT,
                JobParameters.REASON_TIMEOUT,
                JobParameters.REASON_DEVICE_IDLE,
            };
            for (int ic = 0; ic < completions.size(); ++ic) {
                SparseIntArray types = completions.valueAt(ic);
                if (types != null) {
                    final long jcToken = proto.start(UidProto.JOB_COMPLETION);

                    proto.write(UidProto.JobCompletion.NAME, completions.keyAt(ic));

                    for (int r : reasons) {
                        long rToken = proto.start(UidProto.JobCompletion.REASON_COUNT);
                        proto.write(UidProto.JobCompletion.ReasonCount.NAME, r);
                        proto.write(UidProto.JobCompletion.ReasonCount.COUNT, types.get(r, 0));
                        proto.end(rToken);
                    }

                    proto.end(jcToken);
                }
            }

            // Scheduled jobs (JOB_DATA)
            final ArrayMap<String, ? extends Timer> jobs = u.getJobStats();
            for (int ij = jobs.size() - 1; ij >= 0; --ij) {
                final Timer timer = jobs.valueAt(ij);
                final Timer bgTimer = timer.getSubTimer();
                final long jToken = proto.start(UidProto.JOBS);

                proto.write(UidProto.Job.NAME, jobs.keyAt(ij));
                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
                dumpTimer(proto, UidProto.Job.TOTAL, timer, rawRealtimeUs, which);
                dumpTimer(proto, UidProto.Job.BACKGROUND, bgTimer, rawRealtimeUs, which);

                proto.end(jToken);
            }

            // Modem Controller (MODEM_CONTROLLER_DATA)
            dumpControllerActivityProto(proto, UidProto.MODEM_CONTROLLER,
                    u.getModemControllerActivity(), which);

            // Network stats (NETWORK_DATA)
            final long nToken = proto.start(UidProto.NETWORK);
            proto.write(UidProto.Network.MOBILE_BYTES_RX,
                    u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which));
            proto.write(UidProto.Network.MOBILE_BYTES_TX,
                    u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which));
            proto.write(UidProto.Network.WIFI_BYTES_RX,
                    u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
            proto.write(UidProto.Network.WIFI_BYTES_TX,
                    u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
            proto.write(UidProto.Network.BT_BYTES_RX,
                    u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which));
            proto.write(UidProto.Network.BT_BYTES_TX,
                    u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which));
            proto.write(UidProto.Network.MOBILE_PACKETS_RX,
                    u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which));
            proto.write(UidProto.Network.MOBILE_PACKETS_TX,
                    u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which));
            proto.write(UidProto.Network.WIFI_PACKETS_RX,
                    u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
            proto.write(UidProto.Network.WIFI_PACKETS_TX,
                    u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
            proto.write(UidProto.Network.MOBILE_ACTIVE_DURATION_MS,
                    roundUsToMs(u.getMobileRadioActiveTime(which)));
            proto.write(UidProto.Network.MOBILE_ACTIVE_COUNT,
                    u.getMobileRadioActiveCount(which));
            proto.write(UidProto.Network.MOBILE_WAKEUP_COUNT,
                    u.getMobileRadioApWakeupCount(which));
            proto.write(UidProto.Network.WIFI_WAKEUP_COUNT,
                    u.getWifiRadioApWakeupCount(which));
            proto.write(UidProto.Network.MOBILE_BYTES_BG_RX,
                    u.getNetworkActivityBytes(NETWORK_MOBILE_BG_RX_DATA, which));
            proto.write(UidProto.Network.MOBILE_BYTES_BG_TX,
                    u.getNetworkActivityBytes(NETWORK_MOBILE_BG_TX_DATA, which));
            proto.write(UidProto.Network.WIFI_BYTES_BG_RX,
                    u.getNetworkActivityBytes(NETWORK_WIFI_BG_RX_DATA, which));
            proto.write(UidProto.Network.WIFI_BYTES_BG_TX,
                    u.getNetworkActivityBytes(NETWORK_WIFI_BG_TX_DATA, which));
            proto.write(UidProto.Network.MOBILE_PACKETS_BG_RX,
                    u.getNetworkActivityPackets(NETWORK_MOBILE_BG_RX_DATA, which));
            proto.write(UidProto.Network.MOBILE_PACKETS_BG_TX,
                    u.getNetworkActivityPackets(NETWORK_MOBILE_BG_TX_DATA, which));
            proto.write(UidProto.Network.WIFI_PACKETS_BG_RX,
                    u.getNetworkActivityPackets(NETWORK_WIFI_BG_RX_DATA, which));
            proto.write(UidProto.Network.WIFI_PACKETS_BG_TX,
                    u.getNetworkActivityPackets(NETWORK_WIFI_BG_TX_DATA, which));
            proto.end(nToken);

            // Power use item (POWER_USE_ITEM_DATA)
            BatterySipper bs = uidToSipper.get(uid);
            if (bs != null) {
                final long bsToken = proto.start(UidProto.POWER_USE_ITEM);
                proto.write(UidProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah);
                proto.write(UidProto.PowerUseItem.SHOULD_HIDE, bs.shouldHide);
                proto.write(UidProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah);
                proto.write(UidProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH,
                        bs.proportionalSmearMah);
                proto.end(bsToken);
            }

            // Processes (PROCESS_DATA)
            final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats =
                    u.getProcessStats();
            for (int ipr = processStats.size() - 1; ipr >= 0; --ipr) {
                final Uid.Proc ps = processStats.valueAt(ipr);
                final long prToken = proto.start(UidProto.PROCESS);

                proto.write(UidProto.Process.NAME, processStats.keyAt(ipr));
                proto.write(UidProto.Process.USER_DURATION_MS, ps.getUserTime(which));
                proto.write(UidProto.Process.SYSTEM_DURATION_MS, ps.getSystemTime(which));
                proto.write(UidProto.Process.FOREGROUND_DURATION_MS, ps.getForegroundTime(which));
                proto.write(UidProto.Process.START_COUNT, ps.getStarts(which));
                proto.write(UidProto.Process.ANR_COUNT, ps.getNumAnrs(which));
                proto.write(UidProto.Process.CRASH_COUNT, ps.getNumCrashes(which));

                proto.end(prToken);
            }

            // Sensors (SENSOR_DATA)
            final SparseArray<? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
            for (int ise = 0; ise < sensors.size(); ++ise) {
                final Uid.Sensor se = sensors.valueAt(ise);
                final Timer timer = se.getSensorTime();
                if (timer == null) {
                    continue;
                }
                final Timer bgTimer = se.getSensorBackgroundTime();
                final int sensorNumber = sensors.keyAt(ise);
                final long seToken = proto.start(UidProto.SENSORS);

                proto.write(UidProto.Sensor.ID, sensorNumber);
                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
                dumpTimer(proto, UidProto.Sensor.APPORTIONED, timer, rawRealtimeUs, which);
                dumpTimer(proto, UidProto.Sensor.BACKGROUND, bgTimer, rawRealtimeUs, which);

                proto.end(seToken);
            }

            // State times (STATE_TIME_DATA)
            for (int ips = 0; ips < Uid.NUM_PROCESS_STATE; ++ips) {
                long durMs = roundUsToMs(u.getProcessStateTime(ips, rawRealtimeUs, which));
                if (durMs == 0) {
                    continue;
                }
                final long stToken = proto.start(UidProto.STATES);
                proto.write(UidProto.StateTime.STATE, ips);
                proto.write(UidProto.StateTime.DURATION_MS, durMs);
                proto.end(stToken);
            }

            // Syncs (SYNC_DATA)
            final ArrayMap<String, ? extends Timer> syncs = u.getSyncStats();
            for (int isy = syncs.size() - 1; isy >= 0; --isy) {
                final Timer timer = syncs.valueAt(isy);
                final Timer bgTimer = timer.getSubTimer();
                final long syToken = proto.start(UidProto.SYNCS);

                proto.write(UidProto.Sync.NAME, syncs.keyAt(isy));
                // Background uses totalDurationMsLocked, while total uses totalTimeLocked
                dumpTimer(proto, UidProto.Sync.TOTAL, timer, rawRealtimeUs, which);
                dumpTimer(proto, UidProto.Sync.BACKGROUND, bgTimer, rawRealtimeUs, which);

                proto.end(syToken);
            }

            // User activity (USER_ACTIVITY_DATA)
            if (u.hasUserActivity()) {
                for (int i = 0; i < Uid.NUM_USER_ACTIVITY_TYPES; ++i) {
                    int val = u.getUserActivityCount(i, which);
                    if (val != 0) {
                        final long uaToken = proto.start(UidProto.USER_ACTIVITY);
                        proto.write(UidProto.UserActivity.NAME, i);
                        proto.write(UidProto.UserActivity.COUNT, val);
                        proto.end(uaToken);
                    }
                }
            }

            // Vibrator (VIBRATOR_DATA)
            dumpTimer(proto, UidProto.VIBRATOR, u.getVibratorOnTimer(), rawRealtimeUs, which);

            // Video (VIDEO_DATA)
            dumpTimer(proto, UidProto.VIDEO, u.getVideoTurnedOnTimer(), rawRealtimeUs, which);

            // Wakelocks (WAKELOCK_DATA)
            final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
            for (int iw = wakelocks.size() - 1; iw >= 0; --iw) {
                final Uid.Wakelock wl = wakelocks.valueAt(iw);
                final long wToken = proto.start(UidProto.WAKELOCKS);
                proto.write(UidProto.Wakelock.NAME, wakelocks.keyAt(iw));
                dumpTimer(proto, UidProto.Wakelock.FULL, wl.getWakeTime(WAKE_TYPE_FULL),
                        rawRealtimeUs, which);
                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
                if (pTimer != null) {
                    dumpTimer(proto, UidProto.Wakelock.PARTIAL, pTimer, rawRealtimeUs, which);
                    dumpTimer(proto, UidProto.Wakelock.BACKGROUND_PARTIAL, pTimer.getSubTimer(),
                            rawRealtimeUs, which);
                }
                dumpTimer(proto, UidProto.Wakelock.WINDOW, wl.getWakeTime(WAKE_TYPE_WINDOW),
                        rawRealtimeUs, which);
                proto.end(wToken);
            }

            // Wifi Multicast Wakelock (WIFI_MULTICAST_WAKELOCK_DATA)
            dumpTimer(proto, UidProto.WIFI_MULTICAST_WAKELOCK, u.getMulticastWakelockStats(),
                    rawRealtimeUs, which);

            // Wakeup alarms (WAKEUP_ALARM_DATA)
            for (int ipkg = packageStats.size() - 1; ipkg >= 0; --ipkg) {
                final Uid.Pkg ps = packageStats.valueAt(ipkg);
                final ArrayMap<String, ? extends Counter> alarms = ps.getWakeupAlarmStats();
                for (int iwa = alarms.size() - 1; iwa >= 0; --iwa) {
                    final long waToken = proto.start(UidProto.WAKEUP_ALARM);
                    proto.write(UidProto.WakeupAlarm.NAME, alarms.keyAt(iwa));
                    proto.write(UidProto.WakeupAlarm.COUNT,
                            alarms.valueAt(iwa).getCountLocked(which));
                    proto.end(waToken);
                }
            }

            // Wifi Controller (WIFI_CONTROLLER_DATA)
            dumpControllerActivityProto(proto, UidProto.WIFI_CONTROLLER,
                    u.getWifiControllerActivity(), which);

            // Wifi data (WIFI_DATA)
            final long wToken = proto.start(UidProto.WIFI);
            proto.write(UidProto.Wifi.FULL_WIFI_LOCK_DURATION_MS,
                    roundUsToMs(u.getFullWifiLockTime(rawRealtimeUs, which)));
            dumpTimer(proto, UidProto.Wifi.APPORTIONED_SCAN, u.getWifiScanTimer(),
                    rawRealtimeUs, which);
            proto.write(UidProto.Wifi.RUNNING_DURATION_MS,
                    roundUsToMs(u.getWifiRunningTime(rawRealtimeUs, which)));
            dumpTimer(proto, UidProto.Wifi.BACKGROUND_SCAN, u.getWifiScanBackgroundTimer(),
                    rawRealtimeUs, which);
            proto.end(wToken);

            proto.end(uTkn);
        }
    }