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