Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / telemetry / internal / platform / power_monitor / android_power_monitor_controller.py
blob564816394b34d2abd96e9914741e9d4af05897a0
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.
5 from telemetry.internal.util import atexit_with_log
6 import logging
8 from telemetry.internal.platform.power_monitor import android_power_monitor_base
10 def _ReenableChargingIfNeeded(battery):
11 if not battery.GetCharging():
12 battery.SetCharging(True)
13 logging.info('Charging status checked at exit.')
15 class AndroidPowerMonitorController(
16 android_power_monitor_base.AndroidPowerMonitorBase):
17 """
18 PowerMonitor that acts as facade for a list of PowerMonitor objects and uses
19 the first available one.
20 """
21 def __init__(self, power_monitors, battery):
22 super(AndroidPowerMonitorController, self).__init__()
23 self._candidate_power_monitors = power_monitors
24 self._active_monitors = []
25 self._battery = battery
26 atexit_with_log.Register(_ReenableChargingIfNeeded, self._battery)
28 def CanMonitorPower(self):
29 return any(m.CanMonitorPower() for m in self._candidate_power_monitors)
31 def StartMonitoringPower(self, browser):
32 # TODO(rnephew): re-add assert when crbug.com/553601 is solved and
33 # StopMonitoringPower is called in the correct place.
34 if self._active_monitors:
35 logging.warning('StopMonitoringPower() not called when expected. Last '
36 'results are likely not reported.')
37 self.StopMonitoringPower()
38 self._CheckStart()
39 self._ChargingOff(self._battery)
40 self._active_monitors = (
41 [m for m in self._candidate_power_monitors if m.CanMonitorPower()])
42 assert self._active_monitors, 'No available monitor.'
43 for monitor in self._active_monitors:
44 monitor.StartMonitoringPower(browser)
46 @staticmethod
47 def _MergePowerResults(combined_results, monitor_results):
48 """
49 Merges monitor_results into combined_results and leaves monitor_results
50 values if there are merge conflicts.
51 """
52 def _CheckDuplicateKeys(dict_one, dict_two, ignore_list=None):
53 for key in dict_one:
54 if key in dict_two and key not in ignore_list:
55 logging.warning('Found multiple instances of %s in power monitor '
56 'entries. Using newest one.', key)
57 # Sub level power entries.
58 for part in ['platform_info', 'component_utilization']:
59 if part in monitor_results:
60 _CheckDuplicateKeys(combined_results[part], monitor_results[part])
61 combined_results[part].update(monitor_results[part])
63 # Top level power entries.
64 platform_info = combined_results['platform_info'].copy()
65 comp_utilization = combined_results['component_utilization'].copy()
66 _CheckDuplicateKeys(
67 combined_results, monitor_results,
68 ['identifier', 'platform_info', 'component_utilization'])
69 combined_results.update(monitor_results)
70 combined_results['platform_info'] = platform_info
71 combined_results['component_utilization'] = comp_utilization
73 def StopMonitoringPower(self):
74 self._CheckStop()
75 self._ChargingOn(self._battery)
76 try:
77 results = {'platform_info': {}, 'component_utilization': {}}
78 for monitor in self._active_monitors:
79 self._MergePowerResults(results, monitor.StopMonitoringPower())
80 return results
81 finally:
82 self._active_monitors = []
84 def _ChargingOff(self, battery):
85 battery.SetCharging(False)
87 def _ChargingOn(self, battery):
88 if battery.GetCharging():
89 logging.warning('Charging re-enabled during test.'
90 'Results may be inaccurate.')
91 battery.SetCharging(True)