OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 an interface to communicate with the device via the adb command. | 5 """Provides an interface to communicate with the device via the adb command. |
6 | 6 |
7 Assumes adb binary is currently on system path. | 7 Assumes adb binary is currently on system path. |
8 """ | 8 """ |
9 | 9 |
10 import collections | 10 import collections |
11 import datetime | 11 import datetime |
| 12 import inspect |
12 import logging | 13 import logging |
13 import os | 14 import os |
14 import re | 15 import re |
15 import shlex | 16 import shlex |
16 import signal | 17 import signal |
17 import subprocess | 18 import subprocess |
18 import sys | 19 import sys |
19 import tempfile | 20 import tempfile |
20 import time | 21 import time |
21 | 22 |
22 import cmd_helper | 23 import cmd_helper |
23 import constants | 24 import constants |
24 import screenshot | 25 import screenshot |
| 26 import system_properties |
25 | 27 |
26 from utils import host_path_finder | 28 from utils import host_path_finder |
27 | 29 |
28 try: | 30 try: |
29 from pylib import pexpect | 31 from pylib import pexpect |
30 except: | 32 except: |
31 pexpect = None | 33 pexpect = None |
32 | 34 |
33 sys.path.append(os.path.join( | 35 sys.path.append(os.path.join( |
34 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner')) | 36 constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner')) |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 """Returns the timestamp of the given |log_line| in the given year.""" | 223 """Returns the timestamp of the given |log_line| in the given year.""" |
222 try: | 224 try: |
223 return datetime.datetime.strptime('%s-%s' % (year, log_line[:18]), | 225 return datetime.datetime.strptime('%s-%s' % (year, log_line[:18]), |
224 '%Y-%m-%d %H:%M:%S.%f') | 226 '%Y-%m-%d %H:%M:%S.%f') |
225 except (ValueError, IndexError): | 227 except (ValueError, IndexError): |
226 logging.critical('Error reading timestamp from ' + log_line) | 228 logging.critical('Error reading timestamp from ' + log_line) |
227 return None | 229 return None |
228 | 230 |
229 | 231 |
230 class AndroidCommands(object): | 232 class AndroidCommands(object): |
231 """Helper class for communicating with Android device via adb. | 233 """Helper class for communicating with Android device via adb.""" |
232 | 234 |
233 Args: | 235 def __init__(self, device=None, api_strict_mode=False): |
234 device: If given, adb commands are only send to the device of this ID. | 236 """Constructor. |
235 Otherwise commands are sent to all attached devices. | |
236 """ | |
237 | 237 |
238 def __init__(self, device=None): | 238 Args: |
| 239 device: If given, adb commands are only send to the device of this ID. |
| 240 Otherwise commands are sent to all attached devices. |
| 241 api_strict_mode: A boolean indicating whether fatal errors should be |
| 242 raised if this API is used improperly. |
| 243 """ |
239 adb_dir = os.path.dirname(constants.ADB_PATH) | 244 adb_dir = os.path.dirname(constants.ADB_PATH) |
240 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep): | 245 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep): |
241 # Required by third_party/android_testrunner to call directly 'adb'. | 246 # Required by third_party/android_testrunner to call directly 'adb'. |
242 os.environ['PATH'] += os.pathsep + adb_dir | 247 os.environ['PATH'] += os.pathsep + adb_dir |
243 self._adb = adb_interface.AdbInterface() | 248 self._adb = adb_interface.AdbInterface() |
244 if device: | 249 if device: |
245 self._adb.SetTargetSerial(device) | 250 self._adb.SetTargetSerial(device) |
246 self._device = device | 251 self._device = device |
247 self._logcat = None | 252 self._logcat = None |
248 self.logcat_process = None | 253 self.logcat_process = None |
249 self._logcat_tmpoutfile = None | 254 self._logcat_tmpoutfile = None |
250 self._pushed_files = [] | 255 self._pushed_files = [] |
251 self._device_utc_offset = None | 256 self._device_utc_offset = None |
252 self._potential_push_size = 0 | 257 self._potential_push_size = 0 |
253 self._actual_push_size = 0 | 258 self._actual_push_size = 0 |
254 self._external_storage = '' | 259 self._external_storage = '' |
255 self._util_wrapper = '' | 260 self._util_wrapper = '' |
| 261 self._api_strict_mode = api_strict_mode |
| 262 self._system_properties = system_properties.SystemProperties(self.Adb()) |
| 263 |
| 264 if not self._api_strict_mode: |
| 265 logging.warning( |
| 266 'API STRICT MODE IS DISABLED.\n' |
| 267 'It should be enabled as soon as possible as it will eventually ' |
| 268 'become the default.') |
| 269 |
| 270 @property |
| 271 def system_properties(self): |
| 272 return self._system_properties |
256 | 273 |
257 def _LogShell(self, cmd): | 274 def _LogShell(self, cmd): |
258 """Logs the adb shell command.""" | 275 """Logs the adb shell command.""" |
259 if self._device: | 276 if self._device: |
260 device_repr = self._device[-4:] | 277 device_repr = self._device[-4:] |
261 else: | 278 else: |
262 device_repr = '????' | 279 device_repr = '????' |
263 logging.info('[%s]> %s', device_repr, cmd) | 280 logging.info('[%s]> %s', device_repr, cmd) |
264 | 281 |
265 def Adb(self): | 282 def Adb(self): |
266 """Returns our AdbInterface to avoid us wrapping all its methods.""" | 283 """Returns our AdbInterface to avoid us wrapping all its methods.""" |
| 284 # TODO(tonyg): Disable this method when in _api_strict_mode. |
267 return self._adb | 285 return self._adb |
268 | 286 |
269 def GetDevice(self): | 287 def GetDevice(self): |
270 """Returns the device serial.""" | 288 """Returns the device serial.""" |
271 return self._device | 289 return self._device |
272 | 290 |
273 def IsOnline(self): | 291 def IsOnline(self): |
274 """Checks whether the device is online. | 292 """Checks whether the device is online. |
275 | 293 |
276 Returns: | 294 Returns: |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 Args: | 363 Args: |
346 full_reboot: Whether to fully reboot the device or just restart the shell. | 364 full_reboot: Whether to fully reboot the device or just restart the shell. |
347 """ | 365 """ |
348 # TODO(torne): hive can't reboot the device either way without breaking the | 366 # TODO(torne): hive can't reboot the device either way without breaking the |
349 # connection; work out if we can handle this better | 367 # connection; work out if we can handle this better |
350 if os.environ.get('USING_HIVE'): | 368 if os.environ.get('USING_HIVE'): |
351 logging.warning('Ignoring reboot request as we are on hive') | 369 logging.warning('Ignoring reboot request as we are on hive') |
352 return | 370 return |
353 if full_reboot or not self.IsRootEnabled(): | 371 if full_reboot or not self.IsRootEnabled(): |
354 self._adb.SendCommand('reboot') | 372 self._adb.SendCommand('reboot') |
| 373 self._system_properties = system_properties.SystemProperties(self.Adb()) |
355 timeout = 300 | 374 timeout = 300 |
356 retries = 1 | 375 retries = 1 |
357 # Wait for the device to disappear. | 376 # Wait for the device to disappear. |
358 while retries < 10 and self.IsOnline(): | 377 while retries < 10 and self.IsOnline(): |
359 time.sleep(1) | 378 time.sleep(1) |
360 retries += 1 | 379 retries += 1 |
361 else: | 380 else: |
362 self.RestartShell() | 381 self.RestartShell() |
363 timeout = 120 | 382 timeout = 120 |
364 # To run tests we need at least the package manager and the sd card (or | 383 # To run tests we need at least the package manager and the sd card (or |
365 # other external storage) to be ready. | 384 # other external storage) to be ready. |
366 self.WaitForDevicePm() | 385 self.WaitForDevicePm() |
367 self.WaitForSdCardReady(timeout) | 386 self.WaitForSdCardReady(timeout) |
368 | 387 |
369 def Shutdown(self): | 388 def Shutdown(self): |
370 """Shuts down the device.""" | 389 """Shuts down the device.""" |
371 self._adb.SendCommand('reboot -p') | 390 self._adb.SendCommand('reboot -p') |
| 391 self._system_properties = system_properties.SystemProperties(self.Adb()) |
372 | 392 |
373 def Uninstall(self, package): | 393 def Uninstall(self, package): |
374 """Uninstalls the specified package from the device. | 394 """Uninstalls the specified package from the device. |
375 | 395 |
376 Args: | 396 Args: |
377 package: Name of the package to remove. | 397 package: Name of the package to remove. |
378 | 398 |
379 Returns: | 399 Returns: |
380 A status string returned by adb uninstall | 400 A status string returned by adb uninstall |
381 """ | 401 """ |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 set. | 549 set. |
530 """ | 550 """ |
531 logging.info('Waiting for system boot completed...') | 551 logging.info('Waiting for system boot completed...') |
532 self._adb.SendCommand('wait-for-device') | 552 self._adb.SendCommand('wait-for-device') |
533 # Now the device is there, but system not boot completed. | 553 # Now the device is there, but system not boot completed. |
534 # Query the sys.boot_completed flag with a basic command | 554 # Query the sys.boot_completed flag with a basic command |
535 boot_completed = False | 555 boot_completed = False |
536 attempts = 0 | 556 attempts = 0 |
537 wait_period = 5 | 557 wait_period = 5 |
538 while not boot_completed and (attempts * wait_period) < wait_time: | 558 while not boot_completed and (attempts * wait_period) < wait_time: |
539 output = self._adb.SendShellCommand('getprop sys.boot_completed', | 559 output = self.system_properties['sys.boot_completed'] |
540 retry_count=1) | |
541 output = output.strip() | 560 output = output.strip() |
542 if output == '1': | 561 if output == '1': |
543 boot_completed = True | 562 boot_completed = True |
544 else: | 563 else: |
545 # If 'error: xxx' returned when querying the flag, it means | 564 # If 'error: xxx' returned when querying the flag, it means |
546 # adb server lost the connection to the emulator, so restart the adb | 565 # adb server lost the connection to the emulator, so restart the adb |
547 # server. | 566 # server. |
548 if 'error:' in output: | 567 if 'error:' in output: |
549 self.RestartAdbServer() | 568 self.RestartAdbServer() |
550 time.sleep(wait_period) | 569 time.sleep(wait_period) |
(...skipping 13 matching lines...) Expand all Loading... |
564 output = self.RunShellCommand('ls ' + external_storage) | 583 output = self.RunShellCommand('ls ' + external_storage) |
565 if output: | 584 if output: |
566 sdcard_ready = True | 585 sdcard_ready = True |
567 else: | 586 else: |
568 time.sleep(wait_period) | 587 time.sleep(wait_period) |
569 attempts += 1 | 588 attempts += 1 |
570 if not sdcard_ready: | 589 if not sdcard_ready: |
571 raise errors.WaitForResponseTimedOutError( | 590 raise errors.WaitForResponseTimedOutError( |
572 'SD card not ready after %s seconds' % timeout_time) | 591 'SD card not ready after %s seconds' % timeout_time) |
573 | 592 |
| 593 def _CheckCommandIsValid(self, command): |
| 594 """Raises a ValueError if the command is not valid.""" |
| 595 |
| 596 # A dict of commands the user should not run directly and a mapping to the |
| 597 # API they should use instead. |
| 598 preferred_apis = { |
| 599 'getprop': 'system_properties[<PROPERTY>]', |
| 600 'setprop': 'system_properties[<PROPERTY>]', |
| 601 'su': 'RunShellCommandWithSU()', |
| 602 } |
| 603 |
| 604 # A dict of commands to methods that may call them. |
| 605 whitelisted_callers = { |
| 606 'su': 'RunShellCommandWithSU', |
| 607 } |
| 608 |
| 609 base_command = shlex.split(command)[0] |
| 610 if (base_command in preferred_apis and |
| 611 (base_command not in whitelisted_callers or |
| 612 whitelisted_callers[base_command] not in [ |
| 613 f[3] for f in inspect.stack()])): |
| 614 error_msg = ('%s cannot be run directly. Instead use: %s' % |
| 615 (base_command, preferred_apis[base_command])) |
| 616 if self._api_strict_mode: |
| 617 raise ValueError(error_msg) |
| 618 else: |
| 619 logging.warning(error_msg) |
| 620 |
574 # It is tempting to turn this function into a generator, however this is not | 621 # It is tempting to turn this function into a generator, however this is not |
575 # possible without using a private (local) adb_shell instance (to ensure no | 622 # possible without using a private (local) adb_shell instance (to ensure no |
576 # other command interleaves usage of it), which would defeat the main aim of | 623 # other command interleaves usage of it), which would defeat the main aim of |
577 # being able to reuse the adb shell instance across commands. | 624 # being able to reuse the adb shell instance across commands. |
578 def RunShellCommand(self, command, timeout_time=20, log_result=False): | 625 def RunShellCommand(self, command, timeout_time=20, log_result=False): |
579 """Send a command to the adb shell and return the result. | 626 """Send a command to the adb shell and return the result. |
580 | 627 |
581 Args: | 628 Args: |
582 command: String containing the shell command to send. Must not include | 629 command: String containing the shell command to send. Must not include |
583 the single quotes as we use them to escape the whole command. | 630 the single quotes as we use them to escape the whole command. |
584 timeout_time: Number of seconds to wait for command to respond before | 631 timeout_time: Number of seconds to wait for command to respond before |
585 retrying, used by AdbInterface.SendShellCommand. | 632 retrying, used by AdbInterface.SendShellCommand. |
586 log_result: Boolean to indicate whether we should log the result of the | 633 log_result: Boolean to indicate whether we should log the result of the |
587 shell command. | 634 shell command. |
588 | 635 |
589 Returns: | 636 Returns: |
590 list containing the lines of output received from running the command | 637 list containing the lines of output received from running the command |
591 """ | 638 """ |
| 639 self._CheckCommandIsValid(command) |
592 self._LogShell(command) | 640 self._LogShell(command) |
593 if "'" in command: logging.warning(command + " contains ' quotes") | 641 if "'" in command: logging.warning(command + " contains ' quotes") |
594 result = self._adb.SendShellCommand( | 642 result = self._adb.SendShellCommand( |
595 "'%s'" % command, timeout_time).splitlines() | 643 "'%s'" % command, timeout_time).splitlines() |
596 if ['error: device not found'] == result: | 644 if ['error: device not found'] == result: |
597 raise errors.DeviceUnresponsiveError('device not found') | 645 raise errors.DeviceUnresponsiveError('device not found') |
598 if log_result: | 646 if log_result: |
599 self._LogShell('\n'.join(result)) | 647 self._LogShell('\n'.join(result)) |
600 return result | 648 return result |
601 | 649 |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 _TEMP_SCRIPT_FILE_BASE_FMT = 'temp_script_file_%d.sh' | 1041 _TEMP_SCRIPT_FILE_BASE_FMT = 'temp_script_file_%d.sh' |
994 | 1042 |
995 def _GetDeviceTempFileName(self, base_name): | 1043 def _GetDeviceTempFileName(self, base_name): |
996 i = 0 | 1044 i = 0 |
997 while self.FileExistsOnDevice( | 1045 while self.FileExistsOnDevice( |
998 self.GetExternalStorage() + '/' + base_name % i): | 1046 self.GetExternalStorage() + '/' + base_name % i): |
999 i += 1 | 1047 i += 1 |
1000 return self.GetExternalStorage() + '/' + base_name % i | 1048 return self.GetExternalStorage() + '/' + base_name % i |
1001 | 1049 |
1002 def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False): | 1050 def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False): |
1003 return self.RunShellCommand('su -c %s' % command, | 1051 return self.RunShellCommand('su -c %s' % command, timeout_time, log_result) |
1004 timeout_time=timeout_time, | |
1005 log_result=log_result) | |
1006 | 1052 |
1007 def CanAccessProtectedFileContents(self): | 1053 def CanAccessProtectedFileContents(self): |
1008 """Returns True if Get/SetProtectedFileContents would work via "su". | 1054 """Returns True if Get/SetProtectedFileContents would work via "su". |
1009 | 1055 |
1010 Devices running user builds don't have adb root, but may provide "su" which | 1056 Devices running user builds don't have adb root, but may provide "su" which |
1011 can be used for accessing protected files. | 1057 can be used for accessing protected files. |
1012 """ | 1058 """ |
1013 r = self.RunShellCommandWithSU('cat /dev/null') | 1059 r = self.RunShellCommandWithSU('cat /dev/null') |
1014 return r == [] or r[0].strip() == '' | 1060 return r == [] or r[0].strip() == '' |
1015 | 1061 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 r'\s*=\s*\w+\s*$', re.MULTILINE) | 1142 r'\s*=\s*\w+\s*$', re.MULTILINE) |
1097 properties = re.sub(re_replace, '', properties) | 1143 properties = re.sub(re_replace, '', properties) |
1098 if enable: | 1144 if enable: |
1099 properties += '\n%s=all\n' % JAVA_ASSERT_PROPERTY | 1145 properties += '\n%s=all\n' % JAVA_ASSERT_PROPERTY |
1100 | 1146 |
1101 file(temp_props_file.name, 'w').write(properties) | 1147 file(temp_props_file.name, 'w').write(properties) |
1102 self._adb.Push(temp_props_file.name, LOCAL_PROPERTIES_PATH) | 1148 self._adb.Push(temp_props_file.name, LOCAL_PROPERTIES_PATH) |
1103 | 1149 |
1104 # Next, check the current runtime value is what we need, and | 1150 # Next, check the current runtime value is what we need, and |
1105 # if not, set it and report that a reboot is required. | 1151 # if not, set it and report that a reboot is required. |
1106 was_set = 'all' in self.RunShellCommand('getprop ' + JAVA_ASSERT_PROPERTY) | 1152 was_set = 'all' in self.system_properties[JAVA_ASSERT_PROPERTY] |
1107 if was_set == enable: | 1153 if was_set == enable: |
1108 return False | 1154 return False |
1109 | 1155 self.system_properties[JAVA_ASSERT_PROPERTY] = enable and 'all' or '' |
1110 self.RunShellCommand('setprop %s "%s"' % (JAVA_ASSERT_PROPERTY, | |
1111 enable and 'all' or '')) | |
1112 return True | 1156 return True |
1113 | 1157 |
1114 def GetBuildId(self): | 1158 def GetBuildId(self): |
1115 """Returns the build ID of the system (e.g. JRM79C).""" | 1159 """Returns the build ID of the system (e.g. JRM79C).""" |
1116 build_id = self.RunShellCommand('getprop ro.build.id')[0] | 1160 build_id = self.system_properties['ro.build.id'] |
1117 assert build_id | 1161 assert build_id |
1118 return build_id | 1162 return build_id |
1119 | 1163 |
1120 def GetBuildType(self): | 1164 def GetBuildType(self): |
1121 """Returns the build type of the system (e.g. eng).""" | 1165 """Returns the build type of the system (e.g. eng).""" |
1122 build_type = self.RunShellCommand('getprop ro.build.type')[0] | 1166 build_type = self.system_properties['ro.build.type'] |
1123 assert build_type | 1167 assert build_type |
1124 return build_type | 1168 return build_type |
1125 | 1169 |
1126 def GetBuildProduct(self): | 1170 def GetBuildProduct(self): |
1127 """Returns the build product of the device (e.g. maguro).""" | 1171 """Returns the build product of the device (e.g. maguro).""" |
1128 build_product = self.RunShellCommand('getprop ro.build.product')[0] | 1172 build_product = self.system_properties['ro.build.product'] |
1129 assert build_product | 1173 assert build_product |
1130 return build_product | 1174 return build_product |
1131 | 1175 |
1132 def GetProductName(self): | 1176 def GetProductName(self): |
1133 """Returns the product name of the device (e.g. takju).""" | 1177 """Returns the product name of the device (e.g. takju).""" |
1134 name = self.RunShellCommand('getprop ro.product.name')[0] | 1178 name = self.system_properties['ro.product.name'] |
1135 assert name | 1179 assert name |
1136 return name | 1180 return name |
1137 | 1181 |
1138 def GetBuildFingerprint(self): | 1182 def GetBuildFingerprint(self): |
1139 """Returns the build fingerprint of the device.""" | 1183 """Returns the build fingerprint of the device.""" |
1140 build_fingerprint = self.RunShellCommand('getprop ro.build.fingerprint')[0] | 1184 build_fingerprint = self.system_properties['ro.build.fingerprint'] |
1141 assert build_fingerprint | 1185 assert build_fingerprint |
1142 return build_fingerprint | 1186 return build_fingerprint |
1143 | 1187 |
1144 def GetDescription(self): | 1188 def GetDescription(self): |
1145 """Returns the description of the system. | 1189 """Returns the description of the system. |
1146 | 1190 |
1147 For example, "yakju-userdebug 4.1 JRN54F 364167 dev-keys". | 1191 For example, "yakju-userdebug 4.1 JRN54F 364167 dev-keys". |
1148 """ | 1192 """ |
1149 description = self.RunShellCommand('getprop ro.build.description')[0] | 1193 description = self.system_properties['ro.build.description'] |
1150 assert description | 1194 assert description |
1151 return description | 1195 return description |
1152 | 1196 |
1153 def GetProductModel(self): | 1197 def GetProductModel(self): |
1154 """Returns the name of the product model (e.g. "Galaxy Nexus") """ | 1198 """Returns the name of the product model (e.g. "Galaxy Nexus") """ |
1155 model = self.RunShellCommand('getprop ro.product.model')[0] | 1199 model = self.system_properties['ro.product.model'] |
1156 assert model | 1200 assert model |
1157 return model | 1201 return model |
1158 | 1202 |
1159 def GetWifiIP(self): | 1203 def GetWifiIP(self): |
1160 """Returns the wifi IP on the device.""" | 1204 """Returns the wifi IP on the device.""" |
1161 wifi_ip = self.RunShellCommand('getprop dhcp.wlan0.ipaddress')[0] | 1205 wifi_ip = self.system_properties['dhcp.wlan0.ipaddress'] |
1162 # Do not assert here. Devices (e.g. emulators) may not have a WifiIP. | 1206 # Do not assert here. Devices (e.g. emulators) may not have a WifiIP. |
1163 return wifi_ip | 1207 return wifi_ip |
1164 | 1208 |
1165 def GetSubscriberInfo(self): | 1209 def GetSubscriberInfo(self): |
1166 """Returns the device subscriber info (e.g. GSM and device ID) as string.""" | 1210 """Returns the device subscriber info (e.g. GSM and device ID) as string.""" |
1167 iphone_sub = self.RunShellCommand('dumpsys iphonesubinfo') | 1211 iphone_sub = self.RunShellCommand('dumpsys iphonesubinfo') |
1168 assert iphone_sub | 1212 assert iphone_sub |
1169 return '\n'.join(iphone_sub) | 1213 return '\n'.join(iphone_sub) |
1170 | 1214 |
1171 def GetBatteryInfo(self): | 1215 def GetBatteryInfo(self): |
1172 """Returns the device battery info (e.g. status, level, etc) as string.""" | 1216 """Returns the device battery info (e.g. status, level, etc) as string.""" |
1173 battery = self.RunShellCommand('dumpsys battery') | 1217 battery = self.RunShellCommand('dumpsys battery') |
1174 assert battery | 1218 assert battery |
1175 return '\n'.join(battery) | 1219 return '\n'.join(battery) |
1176 | 1220 |
1177 def GetSetupWizardStatus(self): | 1221 def GetSetupWizardStatus(self): |
1178 """Returns the status of the device setup wizard (e.g. DISABLED).""" | 1222 """Returns the status of the device setup wizard (e.g. DISABLED).""" |
1179 status = self.RunShellCommand('getprop ro.setupwizard.mode')[0] | 1223 status = self.system_properties['ro.setupwizard.mode'] |
1180 # On some devices, the status is empty if not otherwise set. In such cases | 1224 # On some devices, the status is empty if not otherwise set. In such cases |
1181 # the caller should expect an empty string to be returned. | 1225 # the caller should expect an empty string to be returned. |
1182 return status | 1226 return status |
1183 | 1227 |
1184 def StartMonitoringLogcat(self, clear=True, logfile=None, filters=None): | 1228 def StartMonitoringLogcat(self, clear=True, logfile=None, filters=None): |
1185 """Starts monitoring the output of logcat, for use with WaitForLogMatch. | 1229 """Starts monitoring the output of logcat, for use with WaitForLogMatch. |
1186 | 1230 |
1187 Args: | 1231 Args: |
1188 clear: If True the existing logcat output will be cleared, to avoiding | 1232 clear: If True the existing logcat output will be cleared, to avoiding |
1189 matching historical output lurking in the log. | 1233 matching historical output lurking in the log. |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1713 """ | 1757 """ |
1714 def __init__(self, output): | 1758 def __init__(self, output): |
1715 self._output = output | 1759 self._output = output |
1716 | 1760 |
1717 def write(self, data): | 1761 def write(self, data): |
1718 data = data.replace('\r\r\n', '\n') | 1762 data = data.replace('\r\r\n', '\n') |
1719 self._output.write(data) | 1763 self._output.write(data) |
1720 | 1764 |
1721 def flush(self): | 1765 def flush(self): |
1722 self._output.flush() | 1766 self._output.flush() |
OLD | NEW |