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