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 """Provides a variety of device interactions based on adb. | 5 """Provides a variety of device interactions based on adb. |
6 | 6 |
7 Eventually, this will be based on adb_wrapper. | 7 Eventually, this will be based on adb_wrapper. |
8 """ | 8 """ |
9 # pylint: disable=unused-argument | 9 # pylint: disable=unused-argument |
10 | 10 |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 should_install = bool(self._GetChangedFilesImpl(apk_path, device_path)) | 405 should_install = bool(self._GetChangedFilesImpl(apk_path, device_path)) |
406 if should_install and not reinstall: | 406 if should_install and not reinstall: |
407 self.adb.Uninstall(package_name) | 407 self.adb.Uninstall(package_name) |
408 else: | 408 else: |
409 should_install = True | 409 should_install = True |
410 if should_install: | 410 if should_install: |
411 self.adb.Install(apk_path, reinstall=reinstall) | 411 self.adb.Install(apk_path, reinstall=reinstall) |
412 | 412 |
413 @decorators.WithTimeoutAndRetriesFromInstance() | 413 @decorators.WithTimeoutAndRetriesFromInstance() |
414 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None, | 414 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None, |
415 as_root=False, single_line=False, | 415 as_root=False, single_line=False, timeout=None, |
416 timeout=None, retries=None): | 416 retries=None): |
417 """Run an ADB shell command. | 417 """Run an ADB shell command. |
418 | 418 |
419 The command to run |cmd| should be a sequence of program arguments or else | 419 The command to run |cmd| should be a sequence of program arguments or else |
420 a single string. | 420 a single string. |
421 | 421 |
422 When |cmd| is a sequence, it is assumed to contain the name of the command | 422 When |cmd| is a sequence, it is assumed to contain the name of the command |
423 to run followed by its arguments. In this case, arguments are passed to the | 423 to run followed by its arguments. In this case, arguments are passed to the |
424 command exactly as given, without any further processing by the shell. This | 424 command exactly as given, without any further processing by the shell. This |
425 allows to easily pass arguments containing spaces or special characters | 425 allows to easily pass arguments containing spaces or special characters |
426 without having to worry about getting quoting right. Whenever possible, it | 426 without having to worry about getting quoting right. Whenever possible, it |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
840 args=(zip_file.name, files)) | 840 args=(zip_file.name, files)) |
841 zip_proc.start() | 841 zip_proc.start() |
842 zip_proc.join() | 842 zip_proc.join() |
843 | 843 |
844 zip_on_device = '%s/tmp.zip' % self.GetExternalStoragePath() | 844 zip_on_device = '%s/tmp.zip' % self.GetExternalStoragePath() |
845 try: | 845 try: |
846 self.adb.Push(zip_file.name, zip_on_device) | 846 self.adb.Push(zip_file.name, zip_on_device) |
847 self.RunShellCommand( | 847 self.RunShellCommand( |
848 ['unzip', zip_on_device], | 848 ['unzip', zip_on_device], |
849 as_root=True, | 849 as_root=True, |
850 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR}, | 850 env={'PATH': '%s:$PATH' % install_commands.BIN_DIR}, |
851 check_return=True) | 851 check_return=True) |
852 finally: | 852 finally: |
853 if zip_proc.is_alive(): | 853 if zip_proc.is_alive(): |
854 zip_proc.terminate() | 854 zip_proc.terminate() |
855 if self.IsOnline(): | 855 if self.IsOnline(): |
856 self.RunShellCommand(['rm', zip_on_device], check_return=True) | 856 self.RunShellCommand(['rm', zip_on_device], check_return=True) |
857 | 857 |
858 @staticmethod | 858 @staticmethod |
859 def _CreateDeviceZip(zip_path, host_device_tuples): | 859 def _CreateDeviceZip(zip_path, host_device_tuples): |
860 with zipfile.ZipFile(zip_path, 'w') as zip_file: | 860 with zipfile.ZipFile(zip_path, 'w') as zip_file: |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 """ | 1290 """ |
1291 if not host_path: | 1291 if not host_path: |
1292 host_path = os.path.abspath('screenshot-%s.png' % _GetTimeStamp()) | 1292 host_path = os.path.abspath('screenshot-%s.png' % _GetTimeStamp()) |
1293 with device_temp_file.DeviceTempFile(self.adb, suffix='.png') as device_tmp: | 1293 with device_temp_file.DeviceTempFile(self.adb, suffix='.png') as device_tmp: |
1294 self.RunShellCommand(['/system/bin/screencap', '-p', device_tmp.name], | 1294 self.RunShellCommand(['/system/bin/screencap', '-p', device_tmp.name], |
1295 check_return=True) | 1295 check_return=True) |
1296 self.PullFile(device_tmp.name, host_path) | 1296 self.PullFile(device_tmp.name, host_path) |
1297 return host_path | 1297 return host_path |
1298 | 1298 |
1299 @decorators.WithTimeoutAndRetriesFromInstance() | 1299 @decorators.WithTimeoutAndRetriesFromInstance() |
1300 def GetIOStats(self, timeout=None, retries=None): | |
1301 """Gets cumulative disk IO stats since boot for all processes. | |
1302 | |
1303 Args: | |
1304 timeout: timeout in seconds | |
1305 retries: number of retries | |
1306 | |
1307 Returns: | |
1308 A dict containing |num_reads|, |num_writes|, |read_ms|, and |write_ms|. | |
1309 | |
1310 Raises: | |
1311 CommandTimeoutError on timeout. | |
1312 DeviceUnreachableError on missing device. | |
1313 """ | |
1314 return self.old_interface.GetIoStats() | |
1315 | |
1316 @decorators.WithTimeoutAndRetriesFromInstance() | |
1317 def GetMemoryUsageForPid(self, pid, timeout=None, retries=None): | 1300 def GetMemoryUsageForPid(self, pid, timeout=None, retries=None): |
1318 """Gets the memory usage for the given PID. | 1301 """Gets the memory usage for the given PID. |
1319 | 1302 |
1320 Args: | 1303 Args: |
1321 pid: PID of the process. | 1304 pid: PID of the process. |
1322 timeout: timeout in seconds | 1305 timeout: timeout in seconds |
1323 retries: number of retries | 1306 retries: number of retries |
1324 | 1307 |
1325 Returns: | 1308 Returns: |
1326 A 2-tuple containing: | 1309 A 2-tuple containing: |
(...skipping 15 matching lines...) Expand all Loading... |
1342 Args: | 1325 Args: |
1343 timeout: timeout in seconds | 1326 timeout: timeout in seconds |
1344 retries: number of retries | 1327 retries: number of retries |
1345 """ | 1328 """ |
1346 return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs) | 1329 return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs) |
1347 | 1330 |
1348 def __str__(self): | 1331 def __str__(self): |
1349 """Returns the device serial.""" | 1332 """Returns the device serial.""" |
1350 return self.adb.GetDeviceSerial() | 1333 return self.adb.GetDeviceSerial() |
1351 | 1334 |
| 1335 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1336 def GetDevicePieWrapper(self, timeout=None, retries=None): |
| 1337 """Gets the absolute path to the run_pie wrapper on the device. |
| 1338 |
| 1339 We have to build our device executables to be PIE, but they need to be able |
| 1340 to run on versions of android that don't support PIE (i.e. ICS and below). |
| 1341 To do so, we push a wrapper to the device that lets older android versions |
| 1342 run PIE executables. This method pushes that wrapper to the device if |
| 1343 necessary and returns the path to it. |
| 1344 |
| 1345 This is exposed publicly to allow clients to write scripts using run_pie |
| 1346 (e.g. md5sum.CalculateDeviceMd5Sum). |
| 1347 |
| 1348 Args: |
| 1349 timeout: timeout in seconds |
| 1350 retries: number of retries |
| 1351 |
| 1352 Returns: |
| 1353 The path to the PIE wrapper on the device, or an empty string if the |
| 1354 device does not require the wrapper. |
| 1355 """ |
| 1356 if 'run_pie' not in self._cache: |
| 1357 pie = '' |
| 1358 if (self.build_version_sdk < |
| 1359 constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN): |
| 1360 host_pie_path = os.path.join(constants.GetOutDirectory(), 'run_pie') |
| 1361 if not os.path.exists(host_pie_path): |
| 1362 raise device_errors.CommandFailedError('Please build run_pie') |
| 1363 pie = '%s/run_pie' % constants.TEST_EXECUTABLE_DIR |
| 1364 self.adb.Push(host_pie_path, pie) |
| 1365 |
| 1366 self._cache['run_pie'] = pie |
| 1367 |
| 1368 return self._cache['run_pie'] |
| 1369 |
1352 @classmethod | 1370 @classmethod |
1353 def parallel(cls, devices=None, async=False): | 1371 def parallel(cls, devices=None, async=False): |
1354 """Creates a Parallelizer to operate over the provided list of devices. | 1372 """Creates a Parallelizer to operate over the provided list of devices. |
1355 | 1373 |
1356 If |devices| is either |None| or an empty list, the Parallelizer will | 1374 If |devices| is either |None| or an empty list, the Parallelizer will |
1357 operate over all attached devices. | 1375 operate over all attached devices. |
1358 | 1376 |
1359 Args: | 1377 Args: |
1360 devices: A list of either DeviceUtils instances or objects from | 1378 devices: A list of either DeviceUtils instances or objects from |
1361 from which DeviceUtils instances can be constructed. If None, | 1379 from which DeviceUtils instances can be constructed. If None, |
1362 all attached devices will be used. | 1380 all attached devices will be used. |
1363 async: If true, returns a Parallelizer that runs operations | 1381 async: If true, returns a Parallelizer that runs operations |
1364 asynchronously. | 1382 asynchronously. |
1365 | 1383 |
1366 Returns: | 1384 Returns: |
1367 A Parallelizer operating over |devices|. | 1385 A Parallelizer operating over |devices|. |
1368 """ | 1386 """ |
1369 if not devices: | 1387 if not devices: |
1370 devices = adb_wrapper.AdbWrapper.GetDevices() | 1388 devices = adb_wrapper.AdbWrapper.GetDevices() |
1371 devices = [d if isinstance(d, cls) else cls(d) for d in devices] | 1389 devices = [d if isinstance(d, cls) else cls(d) for d in devices] |
1372 if async: | 1390 if async: |
1373 return parallelizer.Parallelizer(devices) | 1391 return parallelizer.Parallelizer(devices) |
1374 else: | 1392 else: |
1375 return parallelizer.SyncParallelizer(devices) | 1393 return parallelizer.SyncParallelizer(devices) |
OLD | NEW |