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=W0613 | 9 # pylint: disable=W0613 |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 from pylib.utils import apk_helper | 27 from pylib.utils import apk_helper |
28 from pylib.utils import device_temp_file | 28 from pylib.utils import device_temp_file |
29 from pylib.utils import host_utils | 29 from pylib.utils import host_utils |
30 from pylib.utils import md5sum | 30 from pylib.utils import md5sum |
31 from pylib.utils import parallelizer | 31 from pylib.utils import parallelizer |
32 from pylib.utils import timeout_retry | 32 from pylib.utils import timeout_retry |
33 | 33 |
34 _DEFAULT_TIMEOUT = 30 | 34 _DEFAULT_TIMEOUT = 30 |
35 _DEFAULT_RETRIES = 3 | 35 _DEFAULT_RETRIES = 3 |
36 | 36 |
| 37 # A sentinel object for default values |
| 38 # TODO(jbudorick,perezju): revisit how default values are handled by |
| 39 # the timeout_retry decorators. |
| 40 DEFAULT = object() |
| 41 |
37 | 42 |
38 @decorators.WithExplicitTimeoutAndRetries( | 43 @decorators.WithExplicitTimeoutAndRetries( |
39 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) | 44 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) |
40 def GetAVDs(): | 45 def GetAVDs(): |
41 """Returns a list of Android Virtual Devices. | 46 """Returns a list of Android Virtual Devices. |
42 | 47 |
43 Returns: | 48 Returns: |
44 A list containing the configured AVDs. | 49 A list containing the configured AVDs. |
45 """ | 50 """ |
46 lines = cmd_helper.GetCmdOutput([ | 51 lines = cmd_helper.GetCmdOutput([ |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 Raises: | 144 Raises: |
140 CommandTimeoutError on timeout. | 145 CommandTimeoutError on timeout. |
141 DeviceUnreachableError on missing device. | 146 DeviceUnreachableError on missing device. |
142 """ | 147 """ |
143 try: | 148 try: |
144 self.RunShellCommand('ls /root', check_return=True) | 149 self.RunShellCommand('ls /root', check_return=True) |
145 return True | 150 return True |
146 except device_errors.AdbCommandFailedError: | 151 except device_errors.AdbCommandFailedError: |
147 return False | 152 return False |
148 | 153 |
149 def NeedsSU(self, timeout=None, retries=None): | 154 def NeedsSU(self, timeout=DEFAULT, retries=DEFAULT): |
150 """Checks whether 'su' is needed to access protected resources. | 155 """Checks whether 'su' is needed to access protected resources. |
151 | 156 |
152 Args: | 157 Args: |
153 timeout: timeout in seconds | 158 timeout: timeout in seconds |
154 retries: number of retries | 159 retries: number of retries |
155 | 160 |
156 Returns: | 161 Returns: |
157 True if 'su' is available on the device and is needed to to access | 162 True if 'su' is available on the device and is needed to to access |
158 protected resources; False otherwise if either 'su' is not available | 163 protected resources; False otherwise if either 'su' is not available |
159 (e.g. because the device has a user build), or not needed (because adbd | 164 (e.g. because the device has a user build), or not needed (because adbd |
160 already has root privileges). | 165 already has root privileges). |
161 | 166 |
162 Raises: | 167 Raises: |
163 CommandTimeoutError on timeout. | 168 CommandTimeoutError on timeout. |
164 DeviceUnreachableError on missing device. | 169 DeviceUnreachableError on missing device. |
165 """ | 170 """ |
166 if 'needs_su' not in self._cache: | 171 if 'needs_su' not in self._cache: |
167 try: | 172 try: |
168 self.RunShellCommand('su -c ls /root && ! ls /root', check_return=True, | 173 self.RunShellCommand( |
169 timeout=timeout, retries=retries) | 174 'su -c ls /root && ! ls /root', check_return=True, |
| 175 timeout=self._default_timeout if timeout is DEFAULT else timeout, |
| 176 retries=self._default_retries if retries is DEFAULT else retries) |
170 self._cache['needs_su'] = True | 177 self._cache['needs_su'] = True |
171 except device_errors.AdbCommandFailedError: | 178 except device_errors.AdbCommandFailedError: |
172 self._cache['needs_su'] = False | 179 self._cache['needs_su'] = False |
173 return self._cache['needs_su'] | 180 return self._cache['needs_su'] |
174 | 181 |
175 | 182 |
176 @decorators.WithTimeoutAndRetriesFromInstance() | 183 @decorators.WithTimeoutAndRetriesFromInstance() |
177 def EnableRoot(self, timeout=None, retries=None): | 184 def EnableRoot(self, timeout=None, retries=None): |
178 """Restarts adbd with root privileges. | 185 """Restarts adbd with root privileges. |
179 | 186 |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 | 994 |
988 Returns: | 995 Returns: |
989 True if the device-side property changed and a restart is required as a | 996 True if the device-side property changed and a restart is required as a |
990 result, False otherwise. | 997 result, False otherwise. |
991 | 998 |
992 Raises: | 999 Raises: |
993 CommandTimeoutError on timeout. | 1000 CommandTimeoutError on timeout. |
994 """ | 1001 """ |
995 return self.old_interface.SetJavaAssertsEnabled(enabled) | 1002 return self.old_interface.SetJavaAssertsEnabled(enabled) |
996 | 1003 |
| 1004 |
| 1005 @property |
| 1006 def build_description(self): |
| 1007 """Returns the build description of the system. |
| 1008 |
| 1009 For example: |
| 1010 nakasi-user 4.4.4 KTU84P 1227136 release-keys |
| 1011 """ |
| 1012 return self.GetProp('ro.build.description', cache=True) |
| 1013 |
| 1014 @property |
| 1015 def build_fingerprint(self): |
| 1016 """Returns the build fingerprint of the system. |
| 1017 |
| 1018 For example: |
| 1019 google/nakasi/grouper:4.4.4/KTU84P/1227136:user/release-keys |
| 1020 """ |
| 1021 return self.GetProp('ro.build.fingerprint', cache=True) |
| 1022 |
| 1023 @property |
| 1024 def build_id(self): |
| 1025 """Returns the build ID of the system (e.g. 'KTU84P').""" |
| 1026 return self.GetProp('ro.build.id', cache=True) |
| 1027 |
| 1028 @property |
| 1029 def build_product(self): |
| 1030 """Returns the build product of the system (e.g. 'grouper').""" |
| 1031 return self.GetProp('ro.build.product', cache=True) |
| 1032 |
997 @property | 1033 @property |
998 def build_type(self): | 1034 def build_type(self): |
999 """Returns the build type of the system (e.g. userdebug).""" | 1035 """Returns the build type of the system (e.g. 'user').""" |
1000 return self.GetProp('ro.build.type', cache=True) | 1036 return self.GetProp('ro.build.type', cache=True) |
1001 | 1037 |
1002 def GetProp(self, property_name, cache=False, timeout=None, retries=None): | 1038 @property |
| 1039 def build_version_sdk(self): |
| 1040 """Returns the build version sdk of the system as a number (e.g. 19). |
| 1041 |
| 1042 For version code numbers see: |
| 1043 http://developer.android.com/reference/android/os/Build.VERSION_CODES.html |
| 1044 |
| 1045 For named constants see: |
| 1046 pylib.constants.ANDROID_SDK_VERSION_CODES |
| 1047 |
| 1048 Raises: |
| 1049 CommandFailedError if the build version sdk is not a number. |
| 1050 """ |
| 1051 value = self.GetProp('ro.build.version.sdk', cache=True) |
| 1052 try: |
| 1053 return int(value) |
| 1054 except ValueError: |
| 1055 raise device_errors.CommandFailedError( |
| 1056 'Invalid build version sdk: %r' % value) |
| 1057 |
| 1058 @property |
| 1059 def product_cpu_abi(self): |
| 1060 """Returns the product cpu abi of the device (e.g. 'armeabi-v7a').""" |
| 1061 return self.GetProp('ro.product.cpu.abi', cache=True) |
| 1062 |
| 1063 @property |
| 1064 def product_model(self): |
| 1065 """Returns the name of the product model (e.g. 'Nexus 7').""" |
| 1066 return self.GetProp('ro.product.model', cache=True) |
| 1067 |
| 1068 @property |
| 1069 def product_name(self): |
| 1070 """Returns the product name of the device (e.g. 'nakasi').""" |
| 1071 return self.GetProp('ro.product.name', cache=True) |
| 1072 |
| 1073 def GetProp(self, property_name, cache=False, timeout=DEFAULT, |
| 1074 retries=DEFAULT): |
1003 """Gets a property from the device. | 1075 """Gets a property from the device. |
1004 | 1076 |
1005 Args: | 1077 Args: |
1006 property_name: A string containing the name of the property to get from | 1078 property_name: A string containing the name of the property to get from |
1007 the device. | 1079 the device. |
1008 cache: A boolean indicating whether to cache the value of this property. | 1080 cache: A boolean indicating whether to cache the value of this property. |
1009 timeout: timeout in seconds | 1081 timeout: timeout in seconds |
1010 retries: number of retries | 1082 retries: number of retries |
1011 | 1083 |
1012 Returns: | 1084 Returns: |
1013 The value of the device's |property_name| property. | 1085 The value of the device's |property_name| property. |
1014 | 1086 |
1015 Raises: | 1087 Raises: |
1016 CommandTimeoutError on timeout. | 1088 CommandTimeoutError on timeout. |
1017 """ | 1089 """ |
1018 assert isinstance(property_name, basestring), ( | 1090 assert isinstance(property_name, basestring), ( |
1019 "property_name is not a string: %r" % property_name) | 1091 "property_name is not a string: %r" % property_name) |
1020 | 1092 |
1021 cache_key = '_prop:' + property_name | 1093 cache_key = '_prop:' + property_name |
1022 if cache and cache_key in self._cache: | 1094 if cache and cache_key in self._cache: |
1023 return self._cache[cache_key] | 1095 return self._cache[cache_key] |
1024 else: | 1096 else: |
1025 # timeout and retries are handled down at run shell, because we don't | 1097 # timeout and retries are handled down at run shell, because we don't |
1026 # want to apply them in the other branch when reading from the cache | 1098 # want to apply them in the other branch when reading from the cache |
1027 value = self.RunShellCommand(['getprop', property_name], | 1099 value = self.RunShellCommand( |
1028 single_line=True, check_return=True, | 1100 ['getprop', property_name], single_line=True, check_return=True, |
1029 timeout=timeout, retries=retries) | 1101 timeout=self._default_timeout if timeout is DEFAULT else timeout, |
| 1102 retries=self._default_retries if retries is DEFAULT else retries) |
1030 if cache or cache_key in self._cache: | 1103 if cache or cache_key in self._cache: |
1031 self._cache[cache_key] = value | 1104 self._cache[cache_key] = value |
1032 return value | 1105 return value |
1033 | 1106 |
1034 @decorators.WithTimeoutAndRetriesFromInstance() | 1107 @decorators.WithTimeoutAndRetriesFromInstance() |
1035 def SetProp(self, property_name, value, check=False, timeout=None, | 1108 def SetProp(self, property_name, value, check=False, timeout=None, |
1036 retries=None): | 1109 retries=None): |
1037 """Sets a property on the device. | 1110 """Sets a property on the device. |
1038 | 1111 |
1039 Args: | 1112 Args: |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 Returns: | 1263 Returns: |
1191 A Parallelizer operating over |devices|. | 1264 A Parallelizer operating over |devices|. |
1192 """ | 1265 """ |
1193 if not devices: | 1266 if not devices: |
1194 devices = adb_wrapper.AdbWrapper.GetDevices() | 1267 devices = adb_wrapper.AdbWrapper.GetDevices() |
1195 devices = [d if isinstance(d, cls) else cls(d) for d in devices] | 1268 devices = [d if isinstance(d, cls) else cls(d) for d in devices] |
1196 if async: | 1269 if async: |
1197 return parallelizer.Parallelizer(devices) | 1270 return parallelizer.Parallelizer(devices) |
1198 else: | 1271 else: |
1199 return parallelizer.SyncParallelizer(devices) | 1272 return parallelizer.SyncParallelizer(devices) |
OLD | NEW |