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 |