OLD | NEW |
| (Empty) |
1 # Copyright 2013 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 | |
5 import logging | |
6 from pylib import android_commands | |
7 from pylib.device import device_utils | |
8 | |
9 | |
10 class OmapThrottlingDetector(object): | |
11 """Class to detect and track thermal throttling on an OMAP 4.""" | |
12 OMAP_TEMP_FILE = ('/sys/devices/platform/omap/omap_temp_sensor.0/' | |
13 'temperature') | |
14 | |
15 @staticmethod | |
16 def IsSupported(device): | |
17 return device.FileExists(OmapThrottlingDetector.OMAP_TEMP_FILE) | |
18 | |
19 def __init__(self, device): | |
20 self._device = device | |
21 | |
22 @staticmethod | |
23 def BecameThrottled(log_line): | |
24 return 'omap_thermal_throttle' in log_line | |
25 | |
26 @staticmethod | |
27 def BecameUnthrottled(log_line): | |
28 return 'omap_thermal_unthrottle' in log_line | |
29 | |
30 @staticmethod | |
31 def GetThrottlingTemperature(log_line): | |
32 if 'throttle_delayed_work_fn' in log_line: | |
33 return float([s for s in log_line.split() if s.isdigit()][0]) / 1000.0 | |
34 | |
35 def GetCurrentTemperature(self): | |
36 tempdata = self._device.ReadFile(OmapThrottlingDetector.OMAP_TEMP_FILE) | |
37 return float(tempdata) / 1000.0 | |
38 | |
39 | |
40 class ExynosThrottlingDetector(object): | |
41 """Class to detect and track thermal throttling on an Exynos 5.""" | |
42 @staticmethod | |
43 def IsSupported(device): | |
44 return device.FileExists('/sys/bus/exynos5-core') | |
45 | |
46 def __init__(self, device): | |
47 pass | |
48 | |
49 @staticmethod | |
50 def BecameThrottled(log_line): | |
51 return 'exynos_tmu: Throttling interrupt' in log_line | |
52 | |
53 @staticmethod | |
54 def BecameUnthrottled(log_line): | |
55 return 'exynos_thermal_unthrottle: not throttling' in log_line | |
56 | |
57 @staticmethod | |
58 def GetThrottlingTemperature(_log_line): | |
59 return None | |
60 | |
61 @staticmethod | |
62 def GetCurrentTemperature(): | |
63 return None | |
64 | |
65 | |
66 class ThermalThrottle(object): | |
67 """Class to detect and track thermal throttling. | |
68 | |
69 Usage: | |
70 Wait for IsThrottled() to be False before running test | |
71 After running test call HasBeenThrottled() to find out if the | |
72 test run was affected by thermal throttling. | |
73 """ | |
74 | |
75 def __init__(self, device): | |
76 # TODO(jbudorick) Remove once telemetry gets switched over. | |
77 if isinstance(device, android_commands.AndroidCommands): | |
78 device = device_utils.DeviceUtils(device) | |
79 self._device = device | |
80 self._throttled = False | |
81 self._detector = None | |
82 if OmapThrottlingDetector.IsSupported(device): | |
83 self._detector = OmapThrottlingDetector(device) | |
84 elif ExynosThrottlingDetector.IsSupported(device): | |
85 self._detector = ExynosThrottlingDetector(device) | |
86 | |
87 def HasBeenThrottled(self): | |
88 """True if there has been any throttling since the last call to | |
89 HasBeenThrottled or IsThrottled. | |
90 """ | |
91 return self._ReadLog() | |
92 | |
93 def IsThrottled(self): | |
94 """True if currently throttled.""" | |
95 self._ReadLog() | |
96 return self._throttled | |
97 | |
98 def _ReadLog(self): | |
99 if not self._detector: | |
100 return False | |
101 has_been_throttled = False | |
102 serial_number = str(self._device) | |
103 log = self._device.RunShellCommand('dmesg -c') | |
104 degree_symbol = unichr(0x00B0) | |
105 for line in log: | |
106 if self._detector.BecameThrottled(line): | |
107 if not self._throttled: | |
108 logging.warning('>>> Device %s thermally throttled', serial_number) | |
109 self._throttled = True | |
110 has_been_throttled = True | |
111 elif self._detector.BecameUnthrottled(line): | |
112 if self._throttled: | |
113 logging.warning('>>> Device %s thermally unthrottled', serial_number) | |
114 self._throttled = False | |
115 has_been_throttled = True | |
116 temperature = self._detector.GetThrottlingTemperature(line) | |
117 if temperature is not None: | |
118 logging.info(u'Device %s thermally throttled at %3.1f%sC', | |
119 serial_number, temperature, degree_symbol) | |
120 | |
121 if logging.getLogger().isEnabledFor(logging.DEBUG): | |
122 # Print current temperature of CPU SoC. | |
123 temperature = self._detector.GetCurrentTemperature() | |
124 if temperature is not None: | |
125 logging.debug(u'Current SoC temperature of %s = %3.1f%sC', | |
126 serial_number, temperature, degree_symbol) | |
127 | |
128 # Print temperature of battery, to give a system temperature | |
129 dumpsys_log = self._device.RunShellCommand('dumpsys battery') | |
130 for line in dumpsys_log: | |
131 if 'temperature' in line: | |
132 btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0 | |
133 logging.debug(u'Current battery temperature of %s = %3.1f%sC', | |
134 serial_number, btemp, degree_symbol) | |
135 | |
136 return has_been_throttled | |
137 | |
OLD | NEW |