| Index: tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py
|
| diff --git a/tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py b/tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fae8a47ff1605ba584fcc2252d63cd23dcbbd4be
|
| --- /dev/null
|
| +++ b/tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py
|
| @@ -0,0 +1,93 @@
|
| +# Copyright 2014 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +import telemetry.core.platform.power_monitor as power_monitor
|
| +
|
| +import csv
|
| +
|
| +from collections import defaultdict
|
| +
|
| +
|
| +class DumpsysPowerMonitor(power_monitor.PowerMonitor):
|
| + """PowerMonitor that relies on the dumpsys batterystats to monitor the power
|
| + consumption of a single android application. This measure uses a heuristic
|
| + and is the same information end-users see with the battery application.
|
| + """
|
| + def __init__(self, adb):
|
| + """Constructor.
|
| +
|
| + Args:
|
| + adb: adb proxy.
|
| + """
|
| + super(DumpsysPowerMonitor, self).__init__()
|
| + self._adb = adb
|
| + self._browser = None
|
| +
|
| + def CanMonitorPower(self):
|
| + return self._adb.CanControlUsbCharging()
|
| +
|
| + def StartMonitoringPower(self, browser):
|
| + assert not self._browser, (
|
| + 'Must call StopMonitoringPower().')
|
| + self._browser = browser
|
| + # Disable the charging of the device over USB. This is necessary because the
|
| + # device only collects information about power usage when the device is not
|
| + # charging.
|
| + self._adb.DisableUsbCharging()
|
| +
|
| + def StopMonitoringPower(self):
|
| + assert self._browser, (
|
| + 'StartMonitoringPower() not called.')
|
| + try:
|
| + self._adb.EnableUsbCharging()
|
| + # pylint: disable=W0212
|
| + package = self._browser._browser_backend.package
|
| + # By default, 'dumpsys batterystats' measures power consumption during the
|
| + # last unplugged period.
|
| + result = self._adb.RunShellCommand('dumpsys batterystats -c %s' % package)
|
| + assert result, 'Dumpsys produced no output'
|
| + return DumpsysPowerMonitor.ParseSamplingOutput(package, result)
|
| + finally:
|
| + self._browser = None
|
| +
|
| + @staticmethod
|
| + def ParseSamplingOutput(package, dumpsys_output):
|
| + """Parse output of 'dumpsys batterystats -c'
|
| +
|
| + Returns:
|
| + Dictionary in the format returned by StopMonitoringPower().
|
| + """
|
| + # csv columns
|
| + DUMP_VERSION_INDEX = 0
|
| + COLUMN_TYPE_INDEX = 3
|
| + PACKAGE_UID_INDEX = 4
|
| + PWI_POWER_COMSUMPTION_INDEX = 5
|
| + PWI_UID_INDEX = 1
|
| + PWI_AGGREGATION_INDEX = 2
|
| + PWI_SUBTYPE_INDEX = 4
|
| + csvreader = csv.reader(dumpsys_output)
|
| + entries_by_type = defaultdict(list)
|
| + for entry in csvreader:
|
| + if len(entry) < 4 or entry[DUMP_VERSION_INDEX] != '7':
|
| + continue
|
| + entries_by_type[entry[COLUMN_TYPE_INDEX]].append(entry)
|
| + # Find the uid of for the given package.
|
| + assert package in entries_by_type, 'Expected package not found'
|
| + assert len(entries_by_type[package]) == 1, 'Multiple entries for package.'
|
| + uid = entries_by_type[package][0][PACKAGE_UID_INDEX]
|
| + consumptions_mah = [float(entry[PWI_POWER_COMSUMPTION_INDEX])
|
| + for entry in entries_by_type['pwi']
|
| + if entry[PWI_UID_INDEX] == uid and
|
| + entry[PWI_AGGREGATION_INDEX] == 't' and
|
| + entry[PWI_SUBTYPE_INDEX] == 'uid']
|
| + consumption_mah = sum(consumptions_mah)
|
| + # Converting at a nominal voltage of 4.0V, as those values are obtained by a
|
| + # heuristic, and 4.0V is the voltage we set when using a monsoon device.
|
| + consumption_mwh = consumption_mah * 4.0
|
| + # Raw power usage samples.
|
| + out_dict = {}
|
| + out_dict['identifier'] = 'dumpsys'
|
| + out_dict['power_samples_mw'] = []
|
| + out_dict['energy_consumption_mwh'] = consumption_mwh
|
| + return out_dict
|
|
|