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