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 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 Both devices starting with 'emulator' will be returned in below output: | 71 Both devices starting with 'emulator' will be returned in below output: |
72 | 72 |
73 * daemon not running. starting it now on port 5037 * | 73 * daemon not running. starting it now on port 5037 * |
74 * daemon started successfully * | 74 * daemon started successfully * |
75 List of devices attached | 75 List of devices attached |
76 027c10494100b4d7 device | 76 027c10494100b4d7 device |
77 emulator-5554 offline | 77 emulator-5554 offline |
78 emulator-5558 device | 78 emulator-5558 device |
79 """ | 79 """ |
80 re_device = re.compile('^emulator-[0-9]+', re.MULTILINE) | 80 re_device = re.compile('^emulator-[0-9]+', re.MULTILINE) |
81 devices = re_device.findall(cmd_helper.GetCmdOutput(['adb', 'devices'])) | 81 devices = re_device.findall(cmd_helper.GetCmdOutput([constants.ADB_PATH, |
| 82 'devices'])) |
82 return devices | 83 return devices |
83 | 84 |
84 | 85 |
85 def GetAVDs(): | 86 def GetAVDs(): |
86 """Returns a list of AVDs.""" | 87 """Returns a list of AVDs.""" |
87 re_avd = re.compile('^[ ]+Name: ([a-zA-Z0-9_:.-]+)', re.MULTILINE) | 88 re_avd = re.compile('^[ ]+Name: ([a-zA-Z0-9_:.-]+)', re.MULTILINE) |
88 avds = re_avd.findall(cmd_helper.GetCmdOutput(['android', 'list', 'avd'])) | 89 avds = re_avd.findall(cmd_helper.GetCmdOutput(['android', 'list', 'avd'])) |
89 return avds | 90 return avds |
90 | 91 |
91 | 92 |
92 def GetAttachedDevices(): | 93 def GetAttachedDevices(): |
93 """Returns a list of attached, online android devices. | 94 """Returns a list of attached, online android devices. |
94 | 95 |
95 If a preferred device has been set with ANDROID_SERIAL, it will be first in | 96 If a preferred device has been set with ANDROID_SERIAL, it will be first in |
96 the returned list. | 97 the returned list. |
97 | 98 |
98 Example output: | 99 Example output: |
99 | 100 |
100 * daemon not running. starting it now on port 5037 * | 101 * daemon not running. starting it now on port 5037 * |
101 * daemon started successfully * | 102 * daemon started successfully * |
102 List of devices attached | 103 List of devices attached |
103 027c10494100b4d7 device | 104 027c10494100b4d7 device |
104 emulator-5554 offline | 105 emulator-5554 offline |
105 """ | 106 """ |
106 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) | 107 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) |
107 devices = re_device.findall(cmd_helper.GetCmdOutput(['adb', 'devices'])) | 108 devices = re_device.findall(cmd_helper.GetCmdOutput([constants.ADB_PATH, |
| 109 'devices'])) |
108 preferred_device = os.environ.get('ANDROID_SERIAL') | 110 preferred_device = os.environ.get('ANDROID_SERIAL') |
109 if preferred_device in devices: | 111 if preferred_device in devices: |
110 devices.remove(preferred_device) | 112 devices.remove(preferred_device) |
111 devices.insert(0, preferred_device) | 113 devices.insert(0, preferred_device) |
112 return devices | 114 return devices |
113 | 115 |
114 | 116 |
115 def IsDeviceAttached(device): | 117 def IsDeviceAttached(device): |
116 return device in GetAttachedDevices() | 118 return device in GetAttachedDevices() |
117 | 119 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 200 |
199 class AndroidCommands(object): | 201 class AndroidCommands(object): |
200 """Helper class for communicating with Android device via adb. | 202 """Helper class for communicating with Android device via adb. |
201 | 203 |
202 Args: | 204 Args: |
203 device: If given, adb commands are only send to the device of this ID. | 205 device: If given, adb commands are only send to the device of this ID. |
204 Otherwise commands are sent to all attached devices. | 206 Otherwise commands are sent to all attached devices. |
205 """ | 207 """ |
206 | 208 |
207 def __init__(self, device=None): | 209 def __init__(self, device=None): |
| 210 adb_dir = os.path.dirname(constants.ADB_PATH) |
| 211 if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep): |
| 212 # Required by third_party/android_testrunner to call directly 'adb'. |
| 213 os.environ['PATH'] += os.pathsep + adb_dir |
208 self._adb = adb_interface.AdbInterface() | 214 self._adb = adb_interface.AdbInterface() |
209 if device: | 215 if device: |
210 self._adb.SetTargetSerial(device) | 216 self._adb.SetTargetSerial(device) |
211 self._device = device | 217 self._device = device |
212 self._logcat = None | 218 self._logcat = None |
213 self.logcat_process = None | 219 self.logcat_process = None |
214 self._logcat_tmpoutfile = None | 220 self._logcat_tmpoutfile = None |
215 self._pushed_files = [] | 221 self._pushed_files = [] |
216 self._device_utc_offset = self.RunShellCommand('date +%z')[0] | 222 self._device_utc_offset = self.RunShellCommand('date +%z')[0] |
217 self._md5sum_build_dir = '' | 223 self._md5sum_build_dir = '' |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 if out.strip() != 'remount succeeded': | 408 if out.strip() != 'remount succeeded': |
403 raise errors.MsgException('Remount failed: %s' % out) | 409 raise errors.MsgException('Remount failed: %s' % out) |
404 | 410 |
405 def RestartAdbServer(self): | 411 def RestartAdbServer(self): |
406 """Restart the adb server.""" | 412 """Restart the adb server.""" |
407 self.KillAdbServer() | 413 self.KillAdbServer() |
408 self.StartAdbServer() | 414 self.StartAdbServer() |
409 | 415 |
410 def KillAdbServer(self): | 416 def KillAdbServer(self): |
411 """Kill adb server.""" | 417 """Kill adb server.""" |
412 adb_cmd = ['adb', 'kill-server'] | 418 adb_cmd = [constants.ADB_PATH, 'kill-server'] |
413 return cmd_helper.RunCmd(adb_cmd) | 419 return cmd_helper.RunCmd(adb_cmd) |
414 | 420 |
415 def StartAdbServer(self): | 421 def StartAdbServer(self): |
416 """Start adb server.""" | 422 """Start adb server.""" |
417 adb_cmd = ['adb', 'start-server'] | 423 adb_cmd = [constants.ADB_PATH, 'start-server'] |
418 return cmd_helper.RunCmd(adb_cmd) | 424 return cmd_helper.RunCmd(adb_cmd) |
419 | 425 |
420 def WaitForSystemBootCompleted(self, wait_time): | 426 def WaitForSystemBootCompleted(self, wait_time): |
421 """Waits for targeted system's boot_completed flag to be set. | 427 """Waits for targeted system's boot_completed flag to be set. |
422 | 428 |
423 Args: | 429 Args: |
424 wait_time: time in seconds to wait | 430 wait_time: time in seconds to wait |
425 | 431 |
426 Raises: | 432 Raises: |
427 WaitForResponseTimedOutError if wait_time elapses and flag still not | 433 WaitForResponseTimedOutError if wait_time elapses and flag still not |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 if filters: | 921 if filters: |
916 args.extend(filters) | 922 args.extend(filters) |
917 else: | 923 else: |
918 args.append('*:v') | 924 args.append('*:v') |
919 | 925 |
920 if logfile: | 926 if logfile: |
921 logfile = NewLineNormalizer(logfile) | 927 logfile = NewLineNormalizer(logfile) |
922 | 928 |
923 # Spawn logcat and syncronize with it. | 929 # Spawn logcat and syncronize with it. |
924 for _ in range(4): | 930 for _ in range(4): |
925 self._logcat = pexpect.spawn('adb', args, timeout=10, logfile=logfile) | 931 self._logcat = pexpect.spawn(constants.ADB_PATH, args, timeout=10, |
| 932 logfile=logfile) |
926 self.RunShellCommand('log startup_sync') | 933 self.RunShellCommand('log startup_sync') |
927 if self._logcat.expect(['startup_sync', pexpect.EOF, | 934 if self._logcat.expect(['startup_sync', pexpect.EOF, |
928 pexpect.TIMEOUT]) == 0: | 935 pexpect.TIMEOUT]) == 0: |
929 break | 936 break |
930 self._logcat.close(force=True) | 937 self._logcat.close(force=True) |
931 else: | 938 else: |
932 logging.critical('Error reading from logcat: ' + str(self._logcat.match)) | 939 logging.critical('Error reading from logcat: ' + str(self._logcat.match)) |
933 sys.exit(1) | 940 sys.exit(1) |
934 | 941 |
935 def GetMonitoredLogCat(self): | 942 def GetMonitoredLogCat(self): |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 'to debug)' % | 991 'to debug)' % |
985 (timeout, success_re.pattern)) | 992 (timeout, success_re.pattern)) |
986 except pexpect.EOF: | 993 except pexpect.EOF: |
987 # It seems that sometimes logcat can end unexpectedly. This seems | 994 # It seems that sometimes logcat can end unexpectedly. This seems |
988 # to happen during Chrome startup after a reboot followed by a cache | 995 # to happen during Chrome startup after a reboot followed by a cache |
989 # clean. I don't understand why this happens, but this code deals with | 996 # clean. I don't understand why this happens, but this code deals with |
990 # getting EOF in logcat. | 997 # getting EOF in logcat. |
991 logging.critical('Found EOF in adb logcat. Restarting...') | 998 logging.critical('Found EOF in adb logcat. Restarting...') |
992 # Rerun spawn with original arguments. Note that self._logcat.args[0] is | 999 # Rerun spawn with original arguments. Note that self._logcat.args[0] is |
993 # the path of adb, so we don't want it in the arguments. | 1000 # the path of adb, so we don't want it in the arguments. |
994 self._logcat = pexpect.spawn('adb', | 1001 self._logcat = pexpect.spawn(constants.ADB_PATH, |
995 self._logcat.args[1:], | 1002 self._logcat.args[1:], |
996 timeout=self._logcat.timeout, | 1003 timeout=self._logcat.timeout, |
997 logfile=self._logcat.logfile) | 1004 logfile=self._logcat.logfile) |
998 | 1005 |
999 def StartRecordingLogcat(self, clear=True, filters=['*:v']): | 1006 def StartRecordingLogcat(self, clear=True, filters=['*:v']): |
1000 """Starts recording logcat output to eventually be saved as a string. | 1007 """Starts recording logcat output to eventually be saved as a string. |
1001 | 1008 |
1002 This call should come before some series of tests are run, with either | 1009 This call should come before some series of tests are run, with either |
1003 StopRecordingLogcat or SearchLogcatRecord following the tests. | 1010 StopRecordingLogcat or SearchLogcatRecord following the tests. |
1004 | 1011 |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 """ | 1337 """ |
1331 def __init__(self, output): | 1338 def __init__(self, output): |
1332 self._output = output | 1339 self._output = output |
1333 | 1340 |
1334 def write(self, data): | 1341 def write(self, data): |
1335 data = data.replace('\r\r\n', '\n') | 1342 data = data.replace('\r\r\n', '\n') |
1336 self._output.write(data) | 1343 self._output.write(data) |
1337 | 1344 |
1338 def flush(self): | 1345 def flush(self): |
1339 self._output.flush() | 1346 self._output.flush() |
OLD | NEW |