1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import csv 6import logging 7 8from telemetry.internal.platform.power_monitor import android_power_monitor_base 9 10class DumpsysPowerMonitor(android_power_monitor_base.AndroidPowerMonitorBase): 11 """PowerMonitor that relies on the dumpsys batterystats to monitor the power 12 consumption of a single android application. This measure uses a heuristic 13 and is the same information end-users see with the battery application. 14 Available on Android L and higher releases. 15 """ 16 def __init__(self, battery, platform_backend): 17 """Constructor. 18 19 Args: 20 battery: A BatteryUtil instance. 21 platform_backend: A LinuxBasedPlatformBackend instance. 22 """ 23 super(DumpsysPowerMonitor, self).__init__() 24 self._battery = battery 25 self._browser = None 26 self._platform = platform_backend 27 28 def CanMonitorPower(self): 29 result = self._platform.RunCommand('dumpsys batterystats -c') 30 DUMP_VERSION_INDEX = 0 31 # Dumpsys power data is present in dumpsys versions 8 and 9 32 # which is found on L+ devices. 33 return (csv.reader(result).next()[DUMP_VERSION_INDEX] in ['8', '9']) 34 35 def StartMonitoringPower(self, browser): 36 self._CheckStart() 37 assert browser 38 self._browser = browser 39 # Disable the charging of the device over USB. This is necessary because the 40 # device only collects information about power usage when the device is not 41 # charging. 42 43 def StopMonitoringPower(self): 44 self._CheckStop() 45 assert self._browser 46 package = self._browser._browser_backend.package 47 self._browser = None 48 49 voltage = self._ParseVoltage(self._battery.GetBatteryInfo().get('voltage')) 50 power_data = self._battery.GetPowerData() 51 power_results = self.ProcessPowerData(power_data, voltage, package) 52 self._LogPowerAnomalies(power_results, package) 53 return power_results 54 55 @staticmethod 56 def ProcessPowerData(power_data, voltage, package): 57 package_power_data = power_data['per_package'].get(package) 58 if not package_power_data: 59 logging.warning('No power data for %s in dumpsys output.' % package) 60 package_power = 0 61 else: 62 package_power = sum(package_power_data['data']) 63 64 return {'identifier': 'dumpsys', 65 'power_samples_mw': [], 66 'energy_consumption_mwh': power_data['system_total'] * voltage, 67 'application_energy_consumption_mwh': package_power * voltage} 68