| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import atexit | 5 import atexit |
| 6 import hashlib | 6 import hashlib |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import os.path | 9 import os.path |
| 10 import random | 10 import random |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 subprocess.Popen(unmap_command) | 187 subprocess.Popen(unmap_command) |
| 188 atexit.register(_unmap_port) | 188 atexit.register(_unmap_port) |
| 189 return host_port | 189 return host_port |
| 190 | 190 |
| 191 def _is_shell_package_installed(self): | 191 def _is_shell_package_installed(self): |
| 192 # Adb should print one line if the package is installed and return empty | 192 # Adb should print one line if the package is installed and return empty |
| 193 # string otherwise. | 193 # string otherwise. |
| 194 return len(subprocess.check_output(self._adb_command([ | 194 return len(subprocess.check_output(self._adb_command([ |
| 195 'shell', 'pm', 'list', 'packages', _MOJO_SHELL_PACKAGE_NAME]))) > 0 | 195 'shell', 'pm', 'list', 'packages', _MOJO_SHELL_PACKAGE_NAME]))) > 0 |
| 196 | 196 |
| 197 def _get_api_level(self): |
| 198 """Returns the API level of Android running on the device.""" |
| 199 output = subprocess.check_output(self._adb_command([ |
| 200 'shell', 'getprop', 'ro.build.version.sdk'])) |
| 201 return int(output) |
| 202 |
| 197 @staticmethod | 203 @staticmethod |
| 198 def get_tmp_dir_path(): | 204 def get_tmp_dir_path(): |
| 199 """Returns a path to a cache directory owned by the shell where temporary | 205 """Returns a path to a cache directory owned by the shell where temporary |
| 200 files can be stored. | 206 files can be stored. |
| 201 """ | 207 """ |
| 202 return '/data/data/%s/cache/tmp/' % _MOJO_SHELL_PACKAGE_NAME | 208 return '/data/data/%s/cache/tmp/' % _MOJO_SHELL_PACKAGE_NAME |
| 203 | 209 |
| 204 def pull_file(self, device_path, destination_path, remove_original=False): | 210 def pull_file(self, device_path, destination_path, remove_original=False): |
| 205 """Copies or moves the specified file on the device to the host.""" | 211 """Copies or moves the specified file on the device to the host.""" |
| 206 subprocess.check_call(self._adb_command([ | 212 subprocess.check_call(self._adb_command([ |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 """ | 263 """ |
| 258 device_sha1_path = '/sdcard/%s/%s.sha1' % (_MOJO_SHELL_PACKAGE_NAME, | 264 device_sha1_path = '/sdcard/%s/%s.sha1' % (_MOJO_SHELL_PACKAGE_NAME, |
| 259 'MojoShell') | 265 'MojoShell') |
| 260 apk_sha1 = hashlib.sha1(open(shell_apk_path, 'rb').read()).hexdigest() | 266 apk_sha1 = hashlib.sha1(open(shell_apk_path, 'rb').read()).hexdigest() |
| 261 device_apk_sha1 = subprocess.check_output(self._adb_command([ | 267 device_apk_sha1 = subprocess.check_output(self._adb_command([ |
| 262 'shell', 'cat', device_sha1_path])) | 268 'shell', 'cat', device_sha1_path])) |
| 263 do_install = (apk_sha1 != device_apk_sha1 or | 269 do_install = (apk_sha1 != device_apk_sha1 or |
| 264 not self._is_shell_package_installed()) | 270 not self._is_shell_package_installed()) |
| 265 | 271 |
| 266 if do_install: | 272 if do_install: |
| 267 subprocess.check_call( | 273 install_command = ['install'] |
| 268 self._adb_command(['install', '-r', shell_apk_path, '-i', | 274 install_command += ['-r'] # Allow to overwrite an existing installation. |
| 269 _MOJO_SHELL_PACKAGE_NAME]), | 275 install_command += ['-i', _MOJO_SHELL_PACKAGE_NAME] |
| 276 if self._get_api_level() >= 23: # Check if running Lollipop or later. |
| 277 # Grant all permissions listed in manifest. This flag is available only |
| 278 # in Lollipop or later. |
| 279 install_command += ['-g'] |
| 280 install_command += [shell_apk_path] |
| 281 subprocess.check_call(self._adb_command(install_command), |
| 270 stdout=self.verbose_stdout, stderr=self.verbose_stderr) | 282 stdout=self.verbose_stdout, stderr=self.verbose_stderr) |
| 271 | 283 |
| 272 # Update the stamp on the device. | 284 # Update the stamp on the device. |
| 273 with tempfile.NamedTemporaryFile() as fp: | 285 with tempfile.NamedTemporaryFile() as fp: |
| 274 fp.write(apk_sha1) | 286 fp.write(apk_sha1) |
| 275 fp.flush() | 287 fp.flush() |
| 276 subprocess.check_call(self._adb_command(['push', fp.name, | 288 subprocess.check_call(self._adb_command(['push', fp.name, |
| 277 device_sha1_path]), | 289 device_sha1_path]), |
| 278 stdout=self.verbose_stdout, | 290 stdout=self.verbose_stdout, |
| 279 stderr=self.verbose_stderr) | 291 stderr=self.verbose_stderr) |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 Results.output = rf.read() | 440 Results.output = rf.read() |
| 429 | 441 |
| 430 run_thread = threading.Thread(target=do_run) | 442 run_thread = threading.Thread(target=do_run) |
| 431 run_thread.start() | 443 run_thread.start() |
| 432 run_thread.join(timeout) | 444 run_thread.join(timeout) |
| 433 | 445 |
| 434 if run_thread.is_alive(): | 446 if run_thread.is_alive(): |
| 435 self.stop_shell() | 447 self.stop_shell() |
| 436 return None, Results.output, True | 448 return None, Results.output, True |
| 437 return None, Results.output, False | 449 return None, Results.output, False |
| OLD | NEW |