| 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 |