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 |
11 import collections | 11 import collections |
12 import itertools | 12 import itertools |
13 import logging | 13 import logging |
14 import multiprocessing | 14 import multiprocessing |
15 import os | 15 import os |
| 16 import posixpath |
16 import re | 17 import re |
| 18 import shutil |
17 import sys | 19 import sys |
18 import tempfile | 20 import tempfile |
19 import time | 21 import time |
20 import zipfile | 22 import zipfile |
21 | 23 |
22 import pylib.android_commands | 24 import pylib.android_commands |
23 from pylib import cmd_helper | 25 from pylib import cmd_helper |
24 from pylib import constants | 26 from pylib import constants |
25 from pylib.device import adb_wrapper | 27 from pylib.device import adb_wrapper |
26 from pylib.device import decorators | 28 from pylib.device import decorators |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 def _JoinLines(lines): | 124 def _JoinLines(lines): |
123 # makes sure that the last line is also terminated, and is more memory | 125 # makes sure that the last line is also terminated, and is more memory |
124 # efficient than first appending an end-line to each line and then joining | 126 # efficient than first appending an end-line to each line and then joining |
125 # all of them together. | 127 # all of them together. |
126 return ''.join(s for line in lines for s in (line, '\n')) | 128 return ''.join(s for line in lines for s in (line, '\n')) |
127 | 129 |
128 | 130 |
129 class DeviceUtils(object): | 131 class DeviceUtils(object): |
130 | 132 |
131 _MAX_ADB_COMMAND_LENGTH = 512 | 133 _MAX_ADB_COMMAND_LENGTH = 512 |
| 134 _MAX_ADB_OUTPUT_LENGTH = 32768 |
132 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') | 135 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') |
133 | 136 |
134 # Property in /data/local.prop that controls Java assertions. | 137 # Property in /data/local.prop that controls Java assertions. |
135 JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions' | 138 JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions' |
136 | 139 |
137 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, | 140 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, |
138 default_retries=_DEFAULT_RETRIES): | 141 default_retries=_DEFAULT_RETRIES): |
139 """DeviceUtils constructor. | 142 """DeviceUtils constructor. |
140 | 143 |
141 Args: | 144 Args: |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 Raises: | 933 Raises: |
931 CommandFailedError on failure. | 934 CommandFailedError on failure. |
932 CommandTimeoutError on timeout. | 935 CommandTimeoutError on timeout. |
933 """ | 936 """ |
934 # Create the base dir if it doesn't exist already | 937 # Create the base dir if it doesn't exist already |
935 dirname = os.path.dirname(host_path) | 938 dirname = os.path.dirname(host_path) |
936 if dirname and not os.path.exists(dirname): | 939 if dirname and not os.path.exists(dirname): |
937 os.makedirs(dirname) | 940 os.makedirs(dirname) |
938 self.adb.Pull(device_path, host_path) | 941 self.adb.Pull(device_path, host_path) |
939 | 942 |
| 943 def _ReadFileWithPull(self, device_path): |
| 944 try: |
| 945 d = tempfile.mkdtemp() |
| 946 host_temp_path = os.path.join(d, 'tmp_ReadFileWithPull') |
| 947 self.adb.Pull(device_path, host_temp_path) |
| 948 with open(host_temp_path, 'r') as host_temp: |
| 949 return host_temp.read() |
| 950 finally: |
| 951 if os.path.exists(d): |
| 952 shutil.rmtree(d) |
| 953 |
| 954 _LS_RE = re.compile( |
| 955 r'(?P<perms>\S+) +(?P<owner>\S+) +(?P<group>\S+) +(?:(?P<size>\d+) +)?' |
| 956 + r'(?P<date>\S+) +(?P<time>\S+) +(?P<name>.+)$') |
| 957 |
940 @decorators.WithTimeoutAndRetriesFromInstance() | 958 @decorators.WithTimeoutAndRetriesFromInstance() |
941 def ReadFile(self, device_path, as_root=False, | 959 def ReadFile(self, device_path, as_root=False, |
942 timeout=None, retries=None): | 960 timeout=None, retries=None): |
943 """Reads the contents of a file from the device. | 961 """Reads the contents of a file from the device. |
944 | 962 |
945 Args: | 963 Args: |
946 device_path: A string containing the absolute path of the file to read | 964 device_path: A string containing the absolute path of the file to read |
947 from the device. | 965 from the device. |
948 as_root: A boolean indicating whether the read should be executed with | 966 as_root: A boolean indicating whether the read should be executed with |
949 root privileges. | 967 root privileges. |
950 timeout: timeout in seconds | 968 timeout: timeout in seconds |
951 retries: number of retries | 969 retries: number of retries |
952 | 970 |
953 Returns: | 971 Returns: |
954 The contents of |device_path| as a string. Contents are intepreted using | 972 The contents of |device_path| as a string. Contents are intepreted using |
955 universal newlines, so the caller will see them encoded as '\n'. Also, | 973 universal newlines, so the caller will see them encoded as '\n'. Also, |
956 all lines will be terminated. | 974 all lines will be terminated. |
957 | 975 |
958 Raises: | 976 Raises: |
959 AdbCommandFailedError if the file can't be read. | 977 AdbCommandFailedError if the file can't be read. |
960 CommandTimeoutError on timeout. | 978 CommandTimeoutError on timeout. |
961 DeviceUnreachableError on missing device. | 979 DeviceUnreachableError on missing device. |
962 """ | 980 """ |
963 return _JoinLines(self.RunShellCommand( | 981 # TODO(jbudorick): Implement a generic version of Stat() that handles |
964 ['cat', device_path], as_root=as_root, check_return=True)) | 982 # as_root=True, then switch this implementation to use that. |
| 983 size = None |
| 984 ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root, |
| 985 check_return=True) |
| 986 for line in ls_out: |
| 987 m = self._LS_RE.match(line) |
| 988 if m and m.group('name') == posixpath.basename(device_path): |
| 989 size = int(m.group('size')) |
| 990 break |
| 991 else: |
| 992 logging.warning('Could not determine size of %s.', device_path) |
| 993 |
| 994 if size is None or size <= self._MAX_ADB_OUTPUT_LENGTH: |
| 995 return _JoinLines(self.RunShellCommand( |
| 996 ['cat', device_path], as_root=as_root, check_return=True)) |
| 997 elif as_root and self.NeedsSU(): |
| 998 with device_temp_file.DeviceTempFile(self.adb) as device_temp: |
| 999 self.RunShellCommand(['cp', device_path, device_temp.name], |
| 1000 as_root=True, check_return=True) |
| 1001 return self._ReadFileWithPull(device_temp.name) |
| 1002 else: |
| 1003 return self._ReadFileWithPull(device_path) |
965 | 1004 |
966 def _WriteFileWithPush(self, device_path, contents): | 1005 def _WriteFileWithPush(self, device_path, contents): |
967 with tempfile.NamedTemporaryFile() as host_temp: | 1006 with tempfile.NamedTemporaryFile() as host_temp: |
968 host_temp.write(contents) | 1007 host_temp.write(contents) |
969 host_temp.flush() | 1008 host_temp.flush() |
970 self.adb.Push(host_temp.name, device_path) | 1009 self.adb.Push(host_temp.name, device_path) |
971 | 1010 |
972 @decorators.WithTimeoutAndRetriesFromInstance() | 1011 @decorators.WithTimeoutAndRetriesFromInstance() |
973 def WriteFile(self, device_path, contents, as_root=False, force_push=False, | 1012 def WriteFile(self, device_path, contents, as_root=False, force_push=False, |
974 timeout=None, retries=None): | 1013 timeout=None, retries=None): |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 """ | 1558 """ |
1520 if not devices: | 1559 if not devices: |
1521 devices = adb_wrapper.AdbWrapper.GetDevices() | 1560 devices = adb_wrapper.AdbWrapper.GetDevices() |
1522 if not devices: | 1561 if not devices: |
1523 raise device_errors.NoDevicesError() | 1562 raise device_errors.NoDevicesError() |
1524 devices = [d if isinstance(d, cls) else cls(d) for d in devices] | 1563 devices = [d if isinstance(d, cls) else cls(d) for d in devices] |
1525 if async: | 1564 if async: |
1526 return parallelizer.Parallelizer(devices) | 1565 return parallelizer.Parallelizer(devices) |
1527 else: | 1566 else: |
1528 return parallelizer.SyncParallelizer(devices) | 1567 return parallelizer.SyncParallelizer(devices) |
OLD | NEW |