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 |