| OLD | NEW |
| 1 # Copyright 2015 Google Inc. All rights reserved. | 1 # Copyright 2015 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); | 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # you may not use this file except in compliance with the License. | 4 # you may not use this file except in compliance with the License. |
| 5 # You may obtain a copy of the License at | 5 # You may obtain a copy of the License at |
| 6 # | 6 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 | 7 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # | 8 # |
| 9 # Unless required by applicable law or agreed to in writing, software | 9 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, | 10 # distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 has_su = bool(mode) | 137 has_su = bool(mode) |
| 138 | 138 |
| 139 available_governors = KNOWN_CPU_SCALING_GOVERNOR_VALUES | 139 available_governors = KNOWN_CPU_SCALING_GOVERNOR_VALUES |
| 140 out = device.PullContent( | 140 out = device.PullContent( |
| 141 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors') | 141 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors') |
| 142 if out: | 142 if out: |
| 143 available_governors = sorted(i for i in out.split()) | 143 available_governors = sorted(i for i in out.split()) |
| 144 assert set(available_governors).issubset( | 144 assert set(available_governors).issubset( |
| 145 KNOWN_CPU_SCALING_GOVERNOR_VALUES), available_governors | 145 KNOWN_CPU_SCALING_GOVERNOR_VALUES), available_governors |
| 146 | 146 |
| 147 cpuinfo_max_freq = device.PullContent( | 147 available_frequencies = device.PullContent( |
| 148 '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq') | 148 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies') |
| 149 if cpuinfo_max_freq: | 149 if available_frequencies: |
| 150 cpuinfo_max_freq = int(cpuinfo_max_freq) | 150 available_frequencies = sorted( |
| 151 cpuinfo_min_freq = device.PullContent( | 151 int(i) for i in available_frequencies.strip().split()) |
| 152 '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq') | 152 else: |
| 153 if cpuinfo_min_freq: | 153 # It's possibly an older kernel. In that case, query the min/max instead. |
| 154 cpuinfo_min_freq = int(cpuinfo_min_freq) | 154 cpuinfo_min_freq = device.PullContent( |
| 155 '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq') |
| 156 cpuinfo_max_freq = device.PullContent( |
| 157 '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq') |
| 158 if cpuinfo_min_freq and cpuinfo_max_freq: |
| 159 # In practice there's more CPU speeds than this but there's no way (?) |
| 160 # to query this information. |
| 161 available_frequencies = [int(cpuinfo_min_freq), int(cpuinfo_max_freq)] |
| 155 | 162 |
| 156 cache = DeviceCache( | 163 cache = DeviceCache( |
| 157 properties, external_storage_path, has_su, available_governors, | 164 properties, external_storage_path, has_su, |
| 158 cpuinfo_max_freq, cpuinfo_min_freq) | 165 available_frequencies, available_governors) |
| 159 # Only save the cache if all the calls above worked. | 166 # Only save the cache if all the calls above worked. |
| 160 if all(i is not None for i in cache._asdict().itervalues()): | 167 if all(i is not None for i in cache._asdict().itervalues()): |
| 161 _PER_DEVICE_CACHE.set(device, cache) | 168 _PER_DEVICE_CACHE.set(device, cache) |
| 162 return cache | 169 return cache |
| 163 | 170 |
| 164 | 171 |
| 165 ### Public API. | 172 ### Public API. |
| 166 | 173 |
| 167 | 174 |
| 168 # List of known CPU scaling governor values. | 175 # List of known CPU scaling governor values. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 180 # initialized and that cannot change without formatting the device. | 187 # initialized and that cannot change without formatting the device. |
| 181 DeviceCache = collections.namedtuple( | 188 DeviceCache = collections.namedtuple( |
| 182 'DeviceCache', | 189 'DeviceCache', |
| 183 [ | 190 [ |
| 184 # Cache of /system/build.prop on the Android device. | 191 # Cache of /system/build.prop on the Android device. |
| 185 'build_props', | 192 'build_props', |
| 186 # Cache of $EXTERNAL_STORAGE_PATH. | 193 # Cache of $EXTERNAL_STORAGE_PATH. |
| 187 'external_storage_path', | 194 'external_storage_path', |
| 188 # /system/xbin/su exists. | 195 # /system/xbin/su exists. |
| 189 'has_su', | 196 'has_su', |
| 190 # All the valid CPU scaling governors. | 197 # Valid CPU frequencies. |
| 198 'available_frequencies', |
| 199 # Valid CPU scaling governors. |
| 191 'available_governors', | 200 'available_governors', |
| 192 # CPU frequency limits. | |
| 193 'cpuinfo_max_freq', | |
| 194 'cpuinfo_min_freq', | |
| 195 ]) | 201 ]) |
| 196 | 202 |
| 197 | 203 |
| 198 def Initialize(pub_key, priv_key): | 204 def Initialize(pub_key, priv_key): |
| 199 """Initialize Android support through adb. | 205 """Initialize Android support through adb. |
| 200 | 206 |
| 201 You can steal pub_key, priv_key pair from ~/.android/adbkey and | 207 You can steal pub_key, priv_key pair from ~/.android/adbkey and |
| 202 ~/.android/adbkey.pub. | 208 ~/.android/adbkey.pub. |
| 203 """ | 209 """ |
| 204 with _ADB_KEYS_LOCK: | 210 with _ADB_KEYS_LOCK: |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 | 389 |
| 384 # High level methods. | 390 # High level methods. |
| 385 | 391 |
| 386 def GetCPUScale(self): | 392 def GetCPUScale(self): |
| 387 """Returns the CPU scaling factor.""" | 393 """Returns the CPU scaling factor.""" |
| 388 mapping = { | 394 mapping = { |
| 389 'scaling_cur_freq': u'cur', | 395 'scaling_cur_freq': u'cur', |
| 390 'scaling_governor': u'governor', | 396 'scaling_governor': u'governor', |
| 391 } | 397 } |
| 392 out = { | 398 out = { |
| 393 'max': self.cache.cpuinfo_max_freq, | 399 v: self.PullContent('/sys/devices/system/cpu/cpu0/cpufreq/' + k) |
| 394 'min': self.cache.cpuinfo_min_freq, | 400 for k, v in mapping.iteritems() |
| 395 } | 401 } |
| 396 out.update( | |
| 397 (v, self.PullContent('/sys/devices/system/cpu/cpu0/cpufreq/' + k)) | |
| 398 for k, v in mapping.iteritems()) | |
| 399 return { | 402 return { |
| 400 k: v.strip() if isinstance(v, str) else v for k, v in out.iteritems() | 403 k: v.strip() if isinstance(v, str) else v for k, v in out.iteritems() |
| 401 } | 404 } |
| 402 | 405 |
| 403 def SetCPUScalingGovernor(self, governor): | 406 def SetCPUScalingGovernor(self, governor): |
| 404 """Sets the CPU scaling governor to the one specified. | 407 """Sets the CPU scaling governor to the one specified. |
| 405 | 408 |
| 406 Returns: | 409 Returns: |
| 407 True on success. | 410 True on success. |
| 408 """ | 411 """ |
| 409 assert governor in KNOWN_CPU_SCALING_GOVERNOR_VALUES, repr(governor) | 412 assert governor in KNOWN_CPU_SCALING_GOVERNOR_VALUES, repr(governor) |
| 413 if not self.cache.available_governors: |
| 414 return False |
| 410 if governor not in self.cache.available_governors: | 415 if governor not in self.cache.available_governors: |
| 411 if governor == 'powersave': | 416 if governor == 'powersave': |
| 412 return self.SetCPUSpeed(self.cache.cpuinfo_min_freq) | 417 return self.SetCPUSpeed(self.cache.available_frequencies[0]) |
| 413 if governor == 'ondemand': | 418 if governor == 'ondemand': |
| 414 governor = 'interactive' | 419 governor = 'interactive' |
| 415 elif governor == 'interactive': | 420 elif governor == 'interactive': |
| 416 governor = 'ondemand' | 421 governor = 'ondemand' |
| 417 else: | 422 else: |
| 418 _LOG.warning( | 423 _LOG.warning( |
| 419 '%s.SetCPUScalingGovernor(): Can\'t switch to %s', | 424 '%s.SetCPUScalingGovernor(): Can\'t switch to %s', |
| 420 self.port_path, governor) | 425 self.port_path, governor) |
| 421 return False | 426 return False |
| 422 assert governor in KNOWN_CPU_SCALING_GOVERNOR_VALUES, governor | 427 assert governor in KNOWN_CPU_SCALING_GOVERNOR_VALUES, governor |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 return True | 464 return True |
| 460 | 465 |
| 461 def SetCPUSpeed(self, speed): | 466 def SetCPUSpeed(self, speed): |
| 462 """Enforces strict CPU speed and disable the CPU scaling governor. | 467 """Enforces strict CPU speed and disable the CPU scaling governor. |
| 463 | 468 |
| 464 Returns: | 469 Returns: |
| 465 True on success. | 470 True on success. |
| 466 """ | 471 """ |
| 467 assert isinstance(speed, int), speed | 472 assert isinstance(speed, int), speed |
| 468 assert 10000 <= speed <= 10000000, speed | 473 assert 10000 <= speed <= 10000000, speed |
| 474 if not self.cache.available_frequencies: |
| 475 return False |
| 476 assert speed in self.cache.available_frequencies, ( |
| 477 speed, self.cache.available_frequencies) |
| 469 success = self.SetCPUScalingGovernor('userspace') | 478 success = self.SetCPUScalingGovernor('userspace') |
| 470 if not self.PushContent( | 479 if not self.PushContent( |
| 471 '%d\n' % speed, | 480 '%d\n' % speed, |
| 472 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed'): | 481 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed'): |
| 473 return False | 482 return False |
| 474 # Get it back to confirm. | 483 # Get it back to confirm. |
| 475 val = self.PullContent( | 484 val = self.PullContent( |
| 476 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed') | 485 '/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed') |
| 477 return success and (val or '').strip() == str(speed) | 486 return success and (val or '').strip() == str(speed) |
| 478 | 487 |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 return out | 795 return out |
| 787 | 796 |
| 788 @classmethod | 797 @classmethod |
| 789 def _Connect(cls, constructor, **kwargs): | 798 def _Connect(cls, constructor, **kwargs): |
| 790 """Called by either ConnectDevice or Connect.""" | 799 """Called by either ConnectDevice or Connect.""" |
| 791 if not kwargs.get('rsa_keys'): | 800 if not kwargs.get('rsa_keys'): |
| 792 with _ADB_KEYS_LOCK: | 801 with _ADB_KEYS_LOCK: |
| 793 kwargs['rsa_keys'] = _ADB_KEYS[:] | 802 kwargs['rsa_keys'] = _ADB_KEYS[:] |
| 794 device = constructor(**kwargs) | 803 device = constructor(**kwargs) |
| 795 return HighDevice(device, _InitCache(device)) | 804 return HighDevice(device, _InitCache(device)) |
| OLD | NEW |