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
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
):
18 PowerMonitor that acts as facade for a list of PowerMonitor objects and uses
19 the first available one.
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()
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
)
47 def _MergePowerResults(combined_results
, monitor_results
):
49 Merges monitor_results into combined_results and leaves monitor_results
50 values if there are merge conflicts.
52 def _CheckDuplicateKeys(dict_one
, dict_two
, ignore_list
=None):
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()
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
):
75 self
._ChargingOn
(self
._battery
)
77 results
= {'platform_info': {}, 'component_utilization': {}}
78 for monitor
in self
._active
_monitors
:
79 self
._MergePowerResults
(results
, monitor
.StopMonitoringPower())
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)