1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)# found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import logging 6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfrom pylib import android_commands 7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochfrom pylib.device import device_utils 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class OmapThrottlingDetector(object): 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) """Class to detect and track thermal throttling on an OMAP 4.""" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OMAP_TEMP_FILE = ('/sys/devices/platform/omap/omap_temp_sensor.0/' 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'temperature') 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) @staticmethod 16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch def IsSupported(device): 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return device.FileExists(OmapThrottlingDetector.OMAP_TEMP_FILE) 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch def __init__(self, device): 20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self._device = device 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @staticmethod 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def BecameThrottled(log_line): 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 'omap_thermal_throttle' in log_line 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @staticmethod 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def BecameUnthrottled(log_line): 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 'omap_thermal_unthrottle' in log_line 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @staticmethod 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def GetThrottlingTemperature(log_line): 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if 'throttle_delayed_work_fn' in log_line: 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return float([s for s in log_line.split() if s.isdigit()][0]) / 1000.0 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) def GetCurrentTemperature(self): 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tempdata = self._device.ReadFile(OmapThrottlingDetector.OMAP_TEMP_FILE) 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return float(tempdata[0]) / 1000.0 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ExynosThrottlingDetector(object): 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) """Class to detect and track thermal throttling on an Exynos 5.""" 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) @staticmethod 43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch def IsSupported(device): 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return device.FileExists('/sys/bus/exynos5-core') 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch def __init__(self, device): 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) pass 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @staticmethod 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def BecameThrottled(log_line): 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 'exynos_tmu: Throttling interrupt' in log_line 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @staticmethod 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def BecameUnthrottled(log_line): 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 'exynos_thermal_unthrottle: not throttling' in log_line 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @staticmethod 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def GetThrottlingTemperature(_log_line): 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return None 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) @staticmethod 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) def GetCurrentTemperature(): 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return None 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class ThermalThrottle(object): 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """Class to detect and track thermal throttling. 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Usage: 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Wait for IsThrottled() to be False before running test 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) After running test call HasBeenThrottled() to find out if the 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) test run was affected by thermal throttling. 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """ 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch def __init__(self, device): 76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch # TODO(jbudorick) Remove once telemetry gets switched over. 77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if isinstance(device, android_commands.AndroidCommands): 78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch device = device_utils.DeviceUtils(device) 79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self._device = device 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) self._throttled = False 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._detector = None 82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if OmapThrottlingDetector.IsSupported(device): 83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self._detector = OmapThrottlingDetector(device) 84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch elif ExynosThrottlingDetector.IsSupported(device): 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch self._detector = ExynosThrottlingDetector(device) 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) def HasBeenThrottled(self): 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """True if there has been any throttling since the last call to 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) HasBeenThrottled or IsThrottled. 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """ 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return self._ReadLog() 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) def IsThrottled(self): 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) """True if currently throttled.""" 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) self._ReadLog() 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return self._throttled 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) def _ReadLog(self): 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if not self._detector: 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return False 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) has_been_throttled = False 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) serial_number = str(self._device) 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) log = self._device.RunShellCommand('dmesg -c') 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) degree_symbol = unichr(0x00B0) 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for line in log: 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if self._detector.BecameThrottled(line): 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if not self._throttled: 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.warning('>>> Device %s thermally throttled', serial_number) 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) self._throttled = True 110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) has_been_throttled = True 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) elif self._detector.BecameUnthrottled(line): 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if self._throttled: 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.warning('>>> Device %s thermally unthrottled', serial_number) 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) self._throttled = False 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) has_been_throttled = True 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) temperature = self._detector.GetThrottlingTemperature(line) 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if temperature is not None: 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.info(u'Device %s thermally throttled at %3.1f%sC', 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) serial_number, temperature, degree_symbol) 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if logging.getLogger().isEnabledFor(logging.DEBUG): 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Print current temperature of CPU SoC. 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) temperature = self._detector.GetCurrentTemperature() 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if temperature is not None: 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logging.debug(u'Current SoC temperature of %s = %3.1f%sC', 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) serial_number, temperature, degree_symbol) 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) # Print temperature of battery, to give a system temperature 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) dumpsys_log = self._device.RunShellCommand('dumpsys battery') 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for line in dumpsys_log: 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if 'temperature' in line: 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) logging.debug(u'Current battery temperature of %s = %3.1f%sC', 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) serial_number, btemp, degree_symbol) 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return has_been_throttled 137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 138