Commit 1334c961 authored by qsr@chromium.org's avatar qsr@chromium.org

Update parsing of dumpsys batterystats

The format of dumpsys batterystats has changed. This CL updates the
parsing.

Review URL: https://codereview.chromium.org/402153002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284659 0039d316-1c4b-4281-b951-d872f2087c98
parent 47c345bb
......@@ -57,6 +57,9 @@ class DumpsysPowerMonitor(power_monitor.PowerMonitor):
def ParseSamplingOutput(package, dumpsys_output):
"""Parse output of 'dumpsys batterystats -c'
See:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/BatteryStats.java
Returns:
Dictionary in the format returned by StopMonitoringPower().
"""
......@@ -65,32 +68,53 @@ class DumpsysPowerMonitor(power_monitor.PowerMonitor):
out_dict['identifier'] = 'dumpsys'
out_dict['power_samples_mw'] = []
# csv columns
# The list of useful CSV columns.
# Index of the column containing the format version.
DUMP_VERSION_INDEX = 0
COLUMN_TYPE_INDEX = 3
# Index of the column containing the type of the row.
ROW_TYPE_INDEX = 3
# Index for columns of type unique identifier ('uid')
# Index of the column containing the uid.
PACKAGE_UID_INDEX = 4
PWI_POWER_COMSUMPTION_INDEX = 5
# Index of the column containing the application package.
PACKAGE_NAME_INDEX = 5
# Index for columns of type power use ('pwi')
# The column containing the uid of the item.
PWI_UID_INDEX = 1
# The column containing the type of consumption. Only consumtion since last
# charge are of interest here.
PWI_AGGREGATION_INDEX = 2
PWI_SUBTYPE_INDEX = 4
# The column containing the amount of power used, in mah.
PWI_POWER_COMSUMPTION_INDEX = 5
csvreader = csv.reader(dumpsys_output)
entries_by_type = defaultdict(list)
uid_entries = {}
pwi_entries = defaultdict(list)
for entry in csvreader:
if len(entry) < 4 or entry[DUMP_VERSION_INDEX] != '7':
if entry[DUMP_VERSION_INDEX] != '8':
# Wrong file version.
break
if ROW_TYPE_INDEX >= len(entry):
continue
entries_by_type[entry[COLUMN_TYPE_INDEX]].append(entry)
if entry[ROW_TYPE_INDEX] == 'uid':
current_package = entry[PACKAGE_NAME_INDEX]
assert current_package not in uid_entries
uid_entries[current_package] = entry[PACKAGE_UID_INDEX]
elif (PWI_POWER_COMSUMPTION_INDEX < len(entry) and
entry[ROW_TYPE_INDEX] == 'pwi' and
entry[PWI_AGGREGATION_INDEX] == 'l'):
pwi_entries[entry[PWI_UID_INDEX]].append(
float(entry[PWI_POWER_COMSUMPTION_INDEX]))
# Find the uid of for the given package.
if not package in entries_by_type:
logging.warning('Unable to parse dumpsys output. Please upgrade the OS.')
if not package in uid_entries:
logging.warning('Unable to parse dumpsys output. ' +
'Please upgrade the OS version of the device.')
out_dict['energy_consumption_mwh'] = 0
return out_dict
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']
uid = uid_entries[package]
consumptions_mah = pwi_entries[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.
......
......@@ -12,19 +12,19 @@ from telemetry.core.util import GetUnittestDataDir
class DS2784PowerMonitorMonitorTest(unittest.TestCase):
def testEnergyComsumption(self):
package = 'com.google.android.apps.chrome'
dumpsys_output = os.path.join(GetUnittestDataDir(), 'batterystats_v7.csv')
dumpsys_output = os.path.join(GetUnittestDataDir(), 'batterystats_v8.csv')
with open(dumpsys_output, 'r') as output:
results = (
android_dumpsys_power_monitor.DumpsysPowerMonitor.ParseSamplingOutput(
package, output))
self.assertEqual(results['identifier'], 'dumpsys')
self.assertAlmostEqual(results['energy_consumption_mwh'], 2.924)
self.assertAlmostEqual(results['energy_consumption_mwh'], 95.6)
# Older version of the OS do not have the data.
def testNoData(self):
package = 'com.android.chrome'
dumpsys_output = os.path.join(GetUnittestDataDir(),
'batterystats_v7_no_data.csv')
'batterystats_v8_no_data.csv')
with open(dumpsys_output, 'r') as output:
results = (
android_dumpsys_power_monitor.DumpsysPowerMonitor.ParseSamplingOutput(
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment