Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Unified Diff: tools/telemetry/telemetry/core/platform/power_monitor/android_dumpsys_power_monitor.py

Issue 222413002: Adding dumpsys based power monitor for android. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: W0212 warnings Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698