diff options
| -rw-r--r-- | core/java/android/os/BatteryStats.java | 554 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 13 | ||||
| -rw-r--r-- | core/proto/android/app/jobparameters.proto | 33 | ||||
| -rw-r--r-- | core/proto/android/os/batterystats.proto | 327 | ||||
| -rw-r--r-- | core/proto/android/os/powermanager.proto | 34 |
5 files changed, 906 insertions, 55 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 59956964894f..8682c01ebd85 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -447,8 +447,7 @@ public abstract class BatteryStats implements Parcelable { /** * Returns the max duration if it is being tracked. - * Not all Timer subclasses track the max, total, current durations. - + * Not all Timer subclasses track the max, total, and current durations. */ public long getMaxDurationMsLocked(long elapsedRealtimeMs) { return -1; @@ -456,14 +455,14 @@ public abstract class BatteryStats implements Parcelable { /** * Returns the current time the timer has been active, if it is being tracked. - * Not all Timer subclasses track the max, total, current durations. + * Not all Timer subclasses track the max, total, and current durations. */ public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { return -1; } /** - * Returns the current time the timer has been active, if it is being tracked. + * Returns the total time the timer has been active, if it is being tracked. * * Returns the total cumulative duration (i.e. sum of past durations) that this timer has * been on since reset. @@ -471,7 +470,7 @@ public abstract class BatteryStats implements Parcelable { * depending on the Timer, getTotalTimeLocked may represent the total 'blamed' or 'pooled' * time, rather than the actual time. By contrast, getTotalDurationMsLocked always gives * the actual total time. - * Not all Timer subclasses track the max, total, current durations. + * Not all Timer subclasses track the max, total, and current durations. */ public long getTotalDurationMsLocked(long elapsedRealtimeMs) { return -1; @@ -600,9 +599,17 @@ public abstract class BatteryStats implements Parcelable { public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which); public abstract long getWifiScanTime(long elapsedRealtimeUs, int which); public abstract int getWifiScanCount(int which); + /** + * Returns the timer keeping track of wifi scans. + */ + public abstract Timer getWifiScanTimer(); public abstract int getWifiScanBackgroundCount(int which); public abstract long getWifiScanActualTime(long elapsedRealtimeUs); public abstract long getWifiScanBackgroundTime(long elapsedRealtimeUs); + /** + * Returns the timer keeping track of background wifi scans. + */ + public abstract Timer getWifiScanBackgroundTimer(); public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which); public abstract int getWifiBatchedScanCount(int csphBin, int which); public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which); @@ -2824,6 +2831,10 @@ public abstract class BatteryStats implements Parcelable { } } + private static long roundUsToMs(long timeUs) { + return (timeUs + 500) / 1000; + } + private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) { if (timer != null) { // Convert from microseconds to milliseconds with rounding @@ -3028,8 +3039,7 @@ public abstract class BatteryStats implements Parcelable { Timer timer, long rawRealtime, int which) { if (timer != null) { // Convert from microseconds to milliseconds with rounding - final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) - / 1000; + final long totalTime = roundUsToMs(timer.getTotalTimeLocked(rawRealtime, which)); final int count = timer.getCountLocked(which); if (totalTime != 0 || count != 0) { dumpLine(pw, uid, category, type, totalTime, count); @@ -3052,12 +3062,26 @@ public abstract class BatteryStats implements Parcelable { return; } // Convert from microseconds to milliseconds with rounding - final long totalTimeMs = (timer.getTotalTimeLocked(rawRealtimeUs, which) + 500) / 1000; + final long timeMs = roundUsToMs(timer.getTotalTimeLocked(rawRealtimeUs, which)); final int count = timer.getCountLocked(which); - if (totalTimeMs != 0 || count != 0) { + final long maxDurationMs = timer.getMaxDurationMsLocked(rawRealtimeUs / 1000); + final long curDurationMs = timer.getCurrentDurationMsLocked(rawRealtimeUs / 1000); + final long totalDurationMs = timer.getTotalDurationMsLocked(rawRealtimeUs / 1000); + if (timeMs != 0 || count != 0 || maxDurationMs != -1 || curDurationMs != -1 + || totalDurationMs != -1) { final long token = proto.start(fieldId); - proto.write(TimerProto.DURATION_MS, totalTimeMs); + proto.write(TimerProto.DURATION_MS, timeMs); proto.write(TimerProto.COUNT, count); + // These values will be -1 for timers that don't implement the functionality. + if (maxDurationMs != -1) { + proto.write(TimerProto.MAX_DURATION_MS, maxDurationMs); + } + if (curDurationMs != -1) { + proto.write(TimerProto.CURRENT_DURATION_MS, curDurationMs); + } + if (totalDurationMs != -1) { + proto.write(TimerProto.TOTAL_DURATION_MS, totalDurationMs); + } proto.end(token); } } @@ -3770,7 +3794,7 @@ public abstract class BatteryStats implements Parcelable { linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime, "w", which, linePrefix); - // Only log if we had at lease one wakelock... + // Only log if we had at least one wakelock... if (sb.length() > 0) { String name = wakelocks.keyAt(iw); if (name.indexOf(',') >= 0) { @@ -6126,9 +6150,8 @@ public abstract class BatteryStats implements Parcelable { return; } int count = steps.mNumStepDurations; - long token; for (int i = 0; i < count; ++i) { - token = proto.start(fieldId); + long token = proto.start(fieldId); proto.write(SystemProto.BatteryLevelStep.DURATION_MS, steps.getDurationAt(i)); proto.write(SystemProto.BatteryLevelStep.LEVEL, steps.getLevelAt(i)); @@ -6621,15 +6644,443 @@ public abstract class BatteryStats implements Parcelable { } if ((flags & (DUMP_HISTORY_ONLY | DUMP_DAILY_ONLY)) == 0) { - // TODO: implement dumpProtoAppsLocked(proto, apps); - dumpProtoSystemLocked(context, proto, (flags & DUMP_DEVICE_WIFI_ONLY) != 0); + final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, + (flags & DUMP_DEVICE_WIFI_ONLY) != 0); + helper.create(this); + helper.refreshStats(STATS_SINCE_CHARGED, UserHandle.USER_ALL); + + dumpProtoAppsLocked(proto, helper, apps); + dumpProtoSystemLocked(proto, helper); } proto.end(bToken); proto.flush(); } - private void dumpProtoSystemLocked(Context context, ProtoOutputStream proto, boolean wifiOnly) { + 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); + long sToken = proto.start(UidProto.Package.SERVICES); + + proto.write(UidProto.Package.Service.NAME, serviceStats.keyAt(isvc)); + proto.write(UidProto.Package.Service.START_DURATION_MS, + roundUsToMs(ss.getStartTime(batteryUptimeUs, which))); + proto.write(UidProto.Package.Service.START_COUNT, ss.getStarts(which)); + proto.write(UidProto.Package.Service.LAUNCH_COUNT, ss.getLaunches(which)); + + 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); + } + } + } + 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); + } + + // 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); + } + } + + private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper) { final long sToken = proto.start(BatteryStatsProto.SYSTEM); final long rawUptimeUs = SystemClock.uptimeMillis() * 1000; final long rawRealtimeMs = SystemClock.elapsedRealtime(); @@ -6637,7 +7088,7 @@ public abstract class BatteryStats implements Parcelable { final int which = STATS_SINCE_CHARGED; // Battery data (BATTERY_DATA) - long token = proto.start(SystemProto.BATTERY); + final long bToken = proto.start(SystemProto.BATTERY); proto.write(SystemProto.Battery.START_CLOCK_TIME_MS, getStartClockTime()); proto.write(SystemProto.Battery.START_COUNT, getStartCount()); proto.write(SystemProto.Battery.TOTAL_REALTIME_MS, @@ -6660,10 +7111,10 @@ public abstract class BatteryStats implements Parcelable { getMinLearnedBatteryCapacity()); proto.write(SystemProto.Battery.MAX_LEARNED_BATTERY_CAPACITY_UAH, getMaxLearnedBatteryCapacity()); - proto.end(token); + proto.end(bToken); // Battery discharge (BATTERY_DISCHARGE_DATA) - token = proto.start(SystemProto.BATTERY_DISCHARGE); + final long bdToken = proto.start(SystemProto.BATTERY_DISCHARGE); proto.write(SystemProto.BatteryDischarge.LOWER_BOUND_SINCE_CHARGE, getLowDischargeAmountSinceCharge()); proto.write(SystemProto.BatteryDischarge.UPPER_BOUND_SINCE_CHARGE, @@ -6680,10 +7131,11 @@ public abstract class BatteryStats implements Parcelable { getUahDischargeScreenOff(which) / 1000); proto.write(SystemProto.BatteryDischarge.TOTAL_MAH_SCREEN_DOZE, getUahDischargeScreenDoze(which) / 1000); - proto.end(token); + proto.end(bdToken); // Time remaining long timeRemainingUs = computeChargeTimeRemaining(rawRealtimeUs); + // These are part of a oneof, so we should only set one of them. if (timeRemainingUs >= 0) { // Charge time remaining (CHARGE_TIME_REMAIN_DATA) proto.write(SystemProto.CHARGE_TIME_REMAINING_MS, timeRemainingUs / 1000); @@ -6702,11 +7154,11 @@ public abstract class BatteryStats implements Parcelable { // Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA) for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) { - token = proto.start(SystemProto.DATA_CONNECTION); + final long pdcToken = proto.start(SystemProto.DATA_CONNECTION); proto.write(SystemProto.DataConnection.NAME, i); dumpTimer(proto, SystemProto.DataConnection.TOTAL, getPhoneDataConnectionTimer(i), rawRealtimeUs, which); - proto.end(token); + proto.end(pdcToken); } // Discharge step (DISCHARGE_STEP_DATA) @@ -6729,7 +7181,7 @@ public abstract class BatteryStats implements Parcelable { getModemControllerActivity(), which); // Global network data (GLOBAL_NETWORK_DATA) - token = proto.start(SystemProto.GLOBAL_NETWORK); + final long gnToken = proto.start(SystemProto.GLOBAL_NETWORK); proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_RX, getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which)); proto.write(SystemProto.GlobalNetwork.MOBILE_BYTES_TX, @@ -6750,7 +7202,7 @@ public abstract class BatteryStats implements Parcelable { getNetworkActivityBytes(NETWORK_BT_RX_DATA, which)); proto.write(SystemProto.GlobalNetwork.BT_BYTES_TX, getNetworkActivityBytes(NETWORK_BT_TX_DATA, which)); - proto.end(token); + proto.end(gnToken); // Wifi controller (GLOBAL_WIFI_CONTROLLER_DATA) dumpControllerActivityProto(proto, SystemProto.GLOBAL_WIFI_CONTROLLER, @@ -6758,21 +7210,21 @@ public abstract class BatteryStats implements Parcelable { // Global wifi (GLOBAL_WIFI_DATA) - token = proto.start(SystemProto.GLOBAL_WIFI); + final long gwToken = proto.start(SystemProto.GLOBAL_WIFI); proto.write(SystemProto.GlobalWifi.ON_DURATION_MS, getWifiOnTime(rawRealtimeUs, which) / 1000); proto.write(SystemProto.GlobalWifi.RUNNING_DURATION_MS, getGlobalWifiRunningTime(rawRealtimeUs, which) / 1000); - proto.end(token); + proto.end(gwToken); // Kernel wakelock (KERNEL_WAKELOCK_DATA) final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats(); for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) { - token = proto.start(SystemProto.KERNEL_WAKELOCK); + final long kwToken = proto.start(SystemProto.KERNEL_WAKELOCK); proto.write(SystemProto.KernelWakelock.NAME, ent.getKey()); dumpTimer(proto, SystemProto.KernelWakelock.TOTAL, ent.getValue(), rawRealtimeUs, which); - proto.end(token); + proto.end(kwToken); } // Misc (MISC_DATA) @@ -6802,7 +7254,7 @@ public abstract class BatteryStats implements Parcelable { } } } - token = proto.start(SystemProto.MISC); + final long mToken = proto.start(SystemProto.MISC); proto.write(SystemProto.Misc.SCREEN_ON_DURATION_MS, getScreenOnTime(rawRealtimeUs, which) / 1000); proto.write(SystemProto.Misc.PHONE_ON_DURATION_MS, @@ -6845,11 +7297,7 @@ public abstract class BatteryStats implements Parcelable { getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which)); proto.write(SystemProto.Misc.LONGEST_LIGHT_DOZE_DURATION_MS, getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT)); - proto.end(token); - - final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); - helper.create(this); - helper.refreshStats(which, UserHandle.USER_ALL); + proto.end(mToken); // Power use item (POWER_USE_ITEM_DATA) final List<BatterySipper> sippers = helper.getUsageList(); @@ -6881,7 +7329,7 @@ public abstract class BatteryStats implements Parcelable { n = SystemProto.PowerUseItem.FLASHLIGHT; break; case APP: - // dumpProtoAppLocked will handle this. + // dumpProtoAppsLocked will handle this. continue; case USER: n = SystemProto.PowerUseItem.USER; @@ -6900,7 +7348,7 @@ public abstract class BatteryStats implements Parcelable { n = SystemProto.PowerUseItem.MEMORY; break; } - token = proto.start(SystemProto.POWER_USE_ITEM); + final long puiToken = proto.start(SystemProto.POWER_USE_ITEM); proto.write(SystemProto.PowerUseItem.NAME, n); proto.write(SystemProto.PowerUseItem.UID, uid); proto.write(SystemProto.PowerUseItem.COMPUTED_POWER_MAH, bs.totalPowerMah); @@ -6908,39 +7356,39 @@ public abstract class BatteryStats implements Parcelable { proto.write(SystemProto.PowerUseItem.SCREEN_POWER_MAH, bs.screenPowerMah); proto.write(SystemProto.PowerUseItem.PROPORTIONAL_SMEAR_MAH, bs.proportionalSmearMah); - proto.end(token); + proto.end(puiToken); } } // Power use summary (POWER_USE_SUMMARY_DATA) - token = proto.start(SystemProto.POWER_USE_SUMMARY); + final long pusToken = proto.start(SystemProto.POWER_USE_SUMMARY); proto.write(SystemProto.PowerUseSummary.BATTERY_CAPACITY_MAH, helper.getPowerProfile().getBatteryCapacity()); proto.write(SystemProto.PowerUseSummary.COMPUTED_POWER_MAH, helper.getComputedPower()); proto.write(SystemProto.PowerUseSummary.MIN_DRAINED_POWER_MAH, helper.getMinDrainedPower()); proto.write(SystemProto.PowerUseSummary.MAX_DRAINED_POWER_MAH, helper.getMaxDrainedPower()); - proto.end(token); + proto.end(pusToken); // RPM stats (RESOURCE_POWER_MANAGER_DATA) final Map<String, ? extends Timer> rpmStats = getRpmStats(); final Map<String, ? extends Timer> screenOffRpmStats = getScreenOffRpmStats(); for (Map.Entry<String, ? extends Timer> ent : rpmStats.entrySet()) { - token = proto.start(SystemProto.RESOURCE_POWER_MANAGER); + final long rpmToken = proto.start(SystemProto.RESOURCE_POWER_MANAGER); proto.write(SystemProto.ResourcePowerManager.NAME, ent.getKey()); dumpTimer(proto, SystemProto.ResourcePowerManager.TOTAL, ent.getValue(), rawRealtimeUs, which); dumpTimer(proto, SystemProto.ResourcePowerManager.SCREEN_OFF, screenOffRpmStats.get(ent.getKey()), rawRealtimeUs, which); - proto.end(token); + proto.end(rpmToken); } // Screen brightness (SCREEN_BRIGHTNESS_DATA) for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; ++i) { - token = proto.start(SystemProto.SCREEN_BRIGHTNESS); + final long sbToken = proto.start(SystemProto.SCREEN_BRIGHTNESS); proto.write(SystemProto.ScreenBrightness.NAME, i); dumpTimer(proto, SystemProto.ScreenBrightness.TOTAL, getScreenBrightnessTimer(i), rawRealtimeUs, which); - proto.end(token); + proto.end(sbToken); } // Signal scanning time (SIGNAL_SCANNING_TIME_DATA) @@ -6949,47 +7397,47 @@ public abstract class BatteryStats implements Parcelable { // Phone signal strength (SIGNAL_STRENGTH_TIME_DATA and SIGNAL_STRENGTH_COUNT_DATA) for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; ++i) { - token = proto.start(SystemProto.PHONE_SIGNAL_STRENGTH); + final long pssToken = proto.start(SystemProto.PHONE_SIGNAL_STRENGTH); proto.write(SystemProto.PhoneSignalStrength.NAME, i); dumpTimer(proto, SystemProto.PhoneSignalStrength.TOTAL, getPhoneSignalStrengthTimer(i), rawRealtimeUs, which); - proto.end(token); + proto.end(pssToken); } // Wakeup reasons (WAKEUP_REASON_DATA) final Map<String, ? extends Timer> wakeupReasons = getWakeupReasonStats(); for (Map.Entry<String, ? extends Timer> ent : wakeupReasons.entrySet()) { - token = proto.start(SystemProto.WAKEUP_REASON); + final long wrToken = proto.start(SystemProto.WAKEUP_REASON); proto.write(SystemProto.WakeupReason.NAME, ent.getKey()); dumpTimer(proto, SystemProto.WakeupReason.TOTAL, ent.getValue(), rawRealtimeUs, which); - proto.end(token); + proto.end(wrToken); } // Wifi signal strength (WIFI_SIGNAL_STRENGTH_TIME_DATA and WIFI_SIGNAL_STRENGTH_COUNT_DATA) for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; ++i) { - token = proto.start(SystemProto.WIFI_SIGNAL_STRENGTH); + final long wssToken = proto.start(SystemProto.WIFI_SIGNAL_STRENGTH); proto.write(SystemProto.WifiSignalStrength.NAME, i); dumpTimer(proto, SystemProto.WifiSignalStrength.TOTAL, getWifiSignalStrengthTimer(i), rawRealtimeUs, which); - proto.end(token); + proto.end(wssToken); } // Wifi state (WIFI_STATE_TIME_DATA and WIFI_STATE_COUNT_DATA) for (int i = 0; i < NUM_WIFI_STATES; ++i) { - token = proto.start(SystemProto.WIFI_STATE); + final long wsToken = proto.start(SystemProto.WIFI_STATE); proto.write(SystemProto.WifiState.NAME, i); dumpTimer(proto, SystemProto.WifiState.TOTAL, getWifiStateTimer(i), rawRealtimeUs, which); - proto.end(token); + proto.end(wsToken); } // Wifi supplicant state (WIFI_SUPPL_STATE_TIME_DATA and WIFI_SUPPL_STATE_COUNT_DATA) for (int i = 0; i < NUM_WIFI_SUPPL_STATES; ++i) { - token = proto.start(SystemProto.WIFI_SUPPLICANT_STATE); + final long wssToken = proto.start(SystemProto.WIFI_SUPPLICANT_STATE); proto.write(SystemProto.WifiSupplicantState.NAME, i); dumpTimer(proto, SystemProto.WifiSupplicantState.TOTAL, getWifiSupplStateTimer(i), rawRealtimeUs, which); - proto.end(token); + proto.end(wssToken); } proto.end(sToken); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 5c310b157c82..239d7091ed3d 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -6428,6 +6428,11 @@ public class BatteryStatsImpl extends BatteryStats { } @Override + public Timer getWifiScanTimer() { + return mWifiScanTimer; + } + + @Override public int getWifiScanBackgroundCount(int which) { if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { return 0; @@ -6454,6 +6459,14 @@ public class BatteryStatsImpl extends BatteryStats { } @Override + public Timer getWifiScanBackgroundTimer() { + if (mWifiScanTimer == null) { + return null; + } + return mWifiScanTimer.getSubTimer(); + } + + @Override public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; if (mWifiBatchedScanTimer[csphBin] == null) { diff --git a/core/proto/android/app/jobparameters.proto b/core/proto/android/app/jobparameters.proto new file mode 100644 index 000000000000..4f6a2a247e72 --- /dev/null +++ b/core/proto/android/app/jobparameters.proto @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +option java_multiple_files = true; + +package android.app; + +/** + * An android.app.JobParameters object. + */ +message JobParametersProto { + enum CancelReason { + REASON_CANCELLED = 0; + REASON_CONSTRAINTS_NOT_SATISFIED = 1; + REASON_PREEMPT = 2; + REASON_TIMEOUT = 3; + REASON_DEVICE_IDLE = 4; + } +} diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto index 38879c03ff7f..c33c0a0e0518 100644 --- a/core/proto/android/os/batterystats.proto +++ b/core/proto/android/os/batterystats.proto @@ -19,6 +19,8 @@ option java_multiple_files = true; package android.os; +import "frameworks/base/core/proto/android/app/jobparameters.proto"; +import "frameworks/base/core/proto/android/os/powermanager.proto"; import "frameworks/base/core/proto/android/telephony/signalstrength.proto"; message BatteryStatsProto { @@ -356,11 +358,12 @@ message SystemProto { optional PowerUseSummary power_use_summary = 18; message ResourcePowerManager { + // Either StateName or StateName.VoterName. optional string name = 1; optional TimerProto total = 2; optional TimerProto screen_off = 3; } - optional ResourcePowerManager resource_power_manager = 19; + repeated ResourcePowerManager resource_power_manager = 19; message ScreenBrightness { enum Name { @@ -436,12 +439,332 @@ message SystemProto { } message TimerProto { + // This may be an apportioned time. optional int64 duration_ms = 1; optional int64 count = 2; + // The max duration if it is being tracked. Not all Timer subclasses + // track the max duration. + optional int64 max_duration_ms = 3; + // The current time the timer has been active, if it is being tracked. + // Not all Timer subclasses track the current duration. + optional int64 current_duration_ms = 4; + // The total cumulative duration (i.e. sum of past durations) that this timer + // has been on since reset. This may differ from duration_ms since, depending + // on the Timer, getTotalTimeLocked may represent the total 'blamed' or + // 'pooled' time, rather than the actual time. By contrast, total_duration_ms + // always gives the actual total time. Not all Timer subclasses track the + // total duration. + optional int64 total_duration_ms = 5; } message UidProto { // Combination of app ID and user ID. optional int32 uid = 1; - repeated string package_names = 2; + + // The statistics associated with a particular package. + message Package { + optional string name = 1; + + message Service { + optional string name = 1; + // Time spent started. + optional int64 start_duration_ms = 2; + optional int32 start_count = 3; + optional int32 launch_count = 4; + } + repeated Service services = 2; + } + repeated Package packages = 2; + + optional ControllerActivityProto bluetooth_controller = 3; + optional ControllerActivityProto modem_controller = 4; + optional ControllerActivityProto wifi_controller = 5; + + // Bluetooth misc data. + message BluetoothMisc { + // Duration spent BLE scanning blamed on this App (i.e. apportioned to this + // app amongst all apps doing BLE scanning; see explanation of 'apportioned' + // in App's comment). + optional TimerProto apportioned_ble_scan = 1; + // Background times aren't apportioned. + optional TimerProto background_ble_scan = 2; + // Running unoptimized BLE scanning, as defined by Bluetooth's + // AppScanStats.recordScanStart. As of May 2017, these are unfiltered, + // non-opportunistic, non-first-match scans. Durations are not + // pooled/apportioned. + optional TimerProto unoptimized_ble_scan = 3; + // Running unoptimized BLE scanning when app is in background. Durations are + // not pooled/apportioned. + optional TimerProto background_unoptimized_ble_scan = 4; + // Count of results returned by BLE scanning. + optional int32 ble_scan_result_count = 5; + // Count of results returned by BLE scans when app is in background. + // (Included in ble_scan_result_count.) + optional int32 background_ble_scan_result_count = 6; + } + optional BluetoothMisc bluetooth_misc = 6; + + message Cpu { + // Total CPU time with processes executing in userspace. Summed up across + // multiple cores. + optional int64 user_duration_ms = 1; + // Total CPU time with processes executing kernel syscalls. Summed up across + // multiple cores. + optional int64 system_duration_ms = 2; + + // CPU time broken down by CPU frequency (go/cpu-battery-metrics). + // + // These are real CPU time measurement from the kernel, so their sum can + // be different from the sum of user_duration_millis and + // system_duration_millis, which are just approximations. Data is not + // tracked when device is charging. + message ByFrequency { + // Index of the frequency in system.cpu_frequency. It starts from 1, to + // make it easier to analyze. + optional int32 frequency_index = 1; + // CPU time in milliseconds. + optional int64 total_duration_ms = 2; + // Screen-off CPU time in milliseconds. + optional int64 screen_off_duration_ms = 3; + } + repeated ByFrequency by_frequency = 3; + } + optional Cpu cpu = 7; + + // Duration is pooled/apportioned. + optional TimerProto audio = 8; + // Duration is pooled/apportioned. + optional TimerProto camera = 9; + // Duration is pooled/apportioned. + optional TimerProto flashlight = 10; + // Duration is not pooled/apportioned. + optional TimerProto foreground_activity = 11; + // Duration is not pooled/apportioned. + optional TimerProto foreground_service = 12; + // Duration is not pooled/apportioned. + optional TimerProto vibrator = 13; + // Duration is pooled/apportioned. + optional TimerProto video = 14; + + message Job { + optional string name = 1; + // Job times aren't apportioned. + optional TimerProto total = 2; + optional TimerProto background = 3; + } + repeated Job jobs = 15; + + message JobCompletion { + // Job name. + optional string name = 1; + + message ReasonCount { + optional android.app.JobParametersProto.CancelReason name = 1; + optional int32 count = 2; + } + repeated ReasonCount reason_count = 2; + }; + repeated JobCompletion job_completion = 16; + + message Network { + // Mobile data traffic (total, background + foreground). + optional int64 mobile_bytes_rx = 1; + optional int64 mobile_bytes_tx = 2; + // Wifi data traffic (total, background + foreground). + optional int64 wifi_bytes_rx = 3; + optional int64 wifi_bytes_tx = 4; + // Bluetooth data traffic (total, background + foreground). + optional int64 bt_bytes_rx = 5; + optional int64 bt_bytes_tx = 6; + // In packets (total, background + foreground). + optional int64 mobile_packets_rx = 7; + optional int64 mobile_packets_tx = 8; + optional int64 wifi_packets_rx = 9; + optional int64 wifi_packets_tx = 10; + // Radio active duration. + optional int64 mobile_active_duration_ms = 11; + optional int32 mobile_active_count = 12; + // Number of times the app woke up the mobile radio. + optional int32 mobile_wakeup_count = 13; + // Number of times the app woke up the wifi radio. + optional int32 wifi_wakeup_count = 14; + // Mobile data traffic in the background only, included in total above. + optional int64 mobile_bytes_bg_rx = 15; + optional int64 mobile_bytes_bg_tx = 16; + // Wifi data traffic in the background only, included in total above. + optional int64 wifi_bytes_bg_rx = 17; + optional int64 wifi_bytes_bg_tx = 18; + // In packets (background only, included in total packets above). + optional int64 mobile_packets_bg_rx = 19; + optional int64 mobile_packets_bg_tx = 20; + optional int64 wifi_packets_bg_rx = 21; + optional int64 wifi_packets_bg_tx = 22; + }; + optional Network network = 17; + + // TODO: combine System and App messages? + message PowerUseItem { + // Estimated power use in mAh. + optional double computed_power_mah = 1; + // Starting in Oreo, Battery Settings has two modes to display the battery + // info. The first is "app usage list". In this mode, items with should_hide + // enabled are hidden. + optional bool should_hide = 2; + // Smeared power from screen usage. Screen usage power is split and smeared + // among apps, based on activity time. + optional double screen_power_mah = 3; + // Smeared power using proportional method. Power usage from hidden sippers + // is smeared to all apps proportionally (except for screen usage). + optional double proportional_smear_mah = 4; + }; + optional PowerUseItem power_use_item = 18; + + // Durations are not pooled/apportioned. + message Process { + optional string name = 1; + // Time spent executing in user code. + optional int64 user_duration_ms = 2; + // Time spent executing in kernel code. + optional int64 system_duration_ms = 3; + // Time the process was running in the foreground. + optional int64 foreground_duration_ms = 4; + // Number of times the process has been started. + optional int32 start_count = 5; + // Number of times the process has had an ANR. + optional int32 anr_count = 6; + // Number of times the process has crashed. + optional int32 crash_count = 7; + }; + repeated Process process = 19; + + message StateTime { + // All of these (non-deprecated) states are mutually exclusive and can be + // added together to find the total time a uid has had any processes running + // at all. + + // In approximate order or priority (top being what the framework considers + // most important and is thus least likely to kill when resources are + // needed: + // top > foreground service > top sleeping > foreground > background > cache + enum State { + // Time this uid has any processes in the top state (or above such as + // persistent). + PROCESS_STATE_TOP = 0; + // Time this uid has any process with a started out bound foreground + // service, but none in the "top" state. + PROCESS_STATE_FOREGROUND_SERVICE = 1; + // Time this uid has any process that is top while the device is sleeping, + // but none in the "foreground service" or better state. Sleeping is + // mostly screen off, but also includes the time when the screen is on but + // the device has not yet been unlocked. + PROCESS_STATE_TOP_SLEEPING = 2; + // Time this uid has any process in an active foreground state, but none + // in the "top sleeping" or better state. + PROCESS_STATE_FOREGROUND = 3; + // Time this uid has any process in an active background state, but none + // in the "foreground" or better state. + PROCESS_STATE_BACKGROUND = 4; + // Time this uid has any processes that are sitting around cached, not in + // one of the other active states. + PROCESS_STATE_CACHED = 5; + } + optional State state = 1; + optional int64 duration_ms = 2; + } + repeated StateTime states = 20; + + message Sensor { + optional int32 id = 1; + optional TimerProto apportioned = 2; + // Background times aren't apportioned. + optional TimerProto background = 3; + } + repeated Sensor sensors = 21; + + message Sync { + optional string name = 1; + // Sync times aren't apportioned. + optional TimerProto total = 2; + optional TimerProto background = 3; + } + repeated Sync syncs = 22; + + message UserActivity { + optional android.os.PowerManagerProto.UserActivityEvent name = 1; + optional int32 count = 2; + }; + repeated UserActivity user_activity = 23; + + // Aggregated wakelock data for an app overall, across all of its wakelocks. + // The Wakelock message holds data about each *individual* wakelock, but it + // cannot be used to ascertain the aggregated time the app spent holding + // wakelocks, since merely summing Wakelock data will either underestimate (in + // the case of wakelock.partial.duration_ms) or overestimate (in the case of + // wakelock.partial.total_duration_ms) the total time, due to overlapping + // wakelocks. AggregatedWakelock, on the other hand, holds overall per-app + // wakelock data. + message AggregatedWakelock { + // The total duration that the app spent holding partial wakelocks. + // It includes both foreground + background use. + optional int64 partial_duration_ms = 1; + // The total duration that the app spent holding partial wakelocks while the + // app was in the background. Subtracting from partial_duration_ms will + // yield foreground usage. + optional int64 background_partial_duration_ms = 2; + }; + optional AggregatedWakelock aggregated_wakelock = 24; + + message Wakelock { + optional string name = 1; + + // Full wakelocks keep the screen on. Based on + // PowerManager.SCREEN_BRIGHT_WAKE_LOCK (deprecated in API 13) and + // PowerManager.SCREEN_DIM_WAKE_LOCK (deprecated in API 17). Current, max, + // and total durations are not tracked for full wakelocks. + optional TimerProto full = 2; + + // Partial wakelocks ensure the CPU is running while allowing the screen + // to turn off. Based on PowerManager.PARTIAL_WAKE_LOCK. + // Partial wakelock metrics are only recorded when the device is unplugged + // *and* the screen is off. Current, max, and total durations are tracked + // for partial wakelocks. + optional TimerProto partial = 3; + + // These fields are for tracking partial wakelocks (see above), but only + // the time the wakelock was held while the app was in a background state. + // Since all background tracking is 'actual', not 'apportioned', + // background_partial.duration_ms is identical to + // background_partial.total_duration_ms. + optional TimerProto background_partial = 4; + + // Window wakelocks keep the screen on. Current, max, and total durations + // are not tracked for window wakelocks. + optional TimerProto window = 5; + }; + repeated Wakelock wakelocks = 25; + + message WakeupAlarm { + // Wakeup alarm name. + optional string name = 1; + // Only includes counts when screen-off (& on battery). + optional int32 count = 2; + } + repeated WakeupAlarm wakeup_alarm = 26; + + message Wifi { + // Duration holding Wifi-lock. This time is apportioned. + optional int64 full_wifi_lock_duration_ms = 1; + // Duration running Wifi. This time is apportioned. + optional int64 running_duration_ms = 2; + // Duration performing Wifi-scan blamed on this App (i.e. apportioned to + // this app amongst all apps doing Wifi-scanning; see explanation of + // 'apportioned' in App's comment). + optional TimerProto apportioned_scan = 3; + // Scans performed when app is in background. (Included in + // apportioned_scan). This value is not apportioned. Subtracting + // background_scan.total_duration_ms from apportioned_scan.total_duration_ms + // will yield foreground usage. + optional TimerProto background_scan = 4; + }; + optional Wifi wifi = 27; } diff --git a/core/proto/android/os/powermanager.proto b/core/proto/android/os/powermanager.proto new file mode 100644 index 000000000000..3bfe5d68eaae --- /dev/null +++ b/core/proto/android/os/powermanager.proto @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +option java_multiple_files = true; + +package android.os; + +message PowerManagerProto { + /* User activity events in PowerManager.java. */ + enum UserActivityEvent { + // Unspecified event type. + USER_ACTIVITY_EVENT_OTHER = 0; + // Button or key pressed or released. + USER_ACTIVITY_EVENT_BUTTON = 1; + // Touch down, move or up. + USER_ACTIVITY_EVENT_TOUCH = 2; + // Accessibility taking action on behalf of user. + USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; + } +} |